adjust param accessing in cluster, simplify and build_elec script

This commit is contained in:
Fabian 2023-06-14 13:28:20 +02:00
parent 12b9356245
commit 45cac01ea3
5 changed files with 109 additions and 144 deletions

View File

@ -316,16 +316,14 @@ rule add_electricity:
rule simplify_network: rule simplify_network:
params: params:
clustering=config["clustering"], simplify_network=config["clustering"]["simplify_network"],
max_hours=config["electricity"]["max_hours"], aggregation_strategies=config["clustering"].get("aggregation_strategies", {}),
focus_weights=config.get("focus_weights", None),
renewable_carriers=config["electricity"]["renewable_carriers"],
costs=config["costs"], costs=config["costs"],
renewable=config["renewable"], max_hours=config["electricity"]["max_hours"],
length_factor=config["lines"]["length_factor"], length_factor=config["lines"]["length_factor"],
p_max_pu=config["links"].get("p_max_pu", 1.0), p_max_pu=config["links"].get("p_max_pu", 1.0),
exclude_carriers=config["clustering"]["simplify_network"].get(
"exclude_carriers", []
),
focus_weights=config.get("focus_weights", None),
solver_name=config["solving"]["solver"]["name"], solver_name=config["solving"]["solver"]["name"],
input: input:
network=RESOURCES + "networks/elec.nc", network=RESOURCES + "networks/elec.nc",
@ -353,14 +351,16 @@ rule simplify_network:
rule cluster_network: rule cluster_network:
params: params:
solver_name=config["solving"]["solver"]["name"], cluster_network=config["clustering"]["cluster_network"],
max_hours=config["electricity"]["max_hours"], aggregation_strategies=config["clustering"].get("aggregation_strategies", {}),
custom_busmap=config["enable"].get("custom_busmap", False),
focus_weights=config.get("focus_weights", None),
renewable_carriers=config["electricity"]["renewable_carriers"],
conventional_carriers=config["electricity"].get("conventional_carriers", []), conventional_carriers=config["electricity"].get("conventional_carriers", []),
costs=config["costs"], costs=config["costs"],
max_hours=config["electricity"]["max_hours"],
length_factor=config["lines"]["length_factor"], length_factor=config["lines"]["length_factor"],
renewable=config["renewable"], solver_name=config["solving"]["solver"]["name"],
clustering=config["clustering"],
custom_busmap=config["enable"].get("custom_busmap", False),
input: input:
network=RESOURCES + "networks/elec_s{simpl}.nc", network=RESOURCES + "networks/elec_s{simpl}.nc",
regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}.geojson", regions_onshore=RESOURCES + "regions_onshore_elec_s{simpl}.geojson",

View File

@ -726,23 +726,23 @@ if __name__ == "__main__":
costs = load_costs( costs = load_costs(
snakemake.input.tech_costs, snakemake.input.tech_costs,
snakemake.params["costs"], snakemake.params.costs,
snakemake.params["electricity"]["max_hours"], snakemake.params.electricity["max_hours"],
Nyears, Nyears,
) )
ppl = load_powerplants(snakemake.input.powerplants) ppl = load_powerplants(snakemake.input.powerplants)
if "renewable_carriers" in snakemake.params["electricity"]: if "renewable_carriers" in snakemake.params.electricity:
renewable_carriers = set(snakemake.params["electricity"]["renewable_carriers"]) renewable_carriers = set(snakemake.params.electricity["renewable_carriers"])
else: else:
logger.warning( logger.warning(
"Missing key `renewable_carriers` under config entry `electricity`. " "Missing key `renewable_carriers` under config entry `electricity`. "
"In future versions, this will raise an error. " "In future versions, this will raise an error. "
"Falling back to carriers listed under `renewable`." "Falling back to carriers listed under `renewable`."
) )
renewable_carriers = snakemake.params["renewable"] renewable_carriers = snakemake.params.renewable
extendable_carriers = snakemake.params["electricity"]["extendable_carriers"] extendable_carriers = snakemake.params.electricity["extendable_carriers"]
if not (set(renewable_carriers) & set(extendable_carriers["Generator"])): if not (set(renewable_carriers) & set(extendable_carriers["Generator"])):
logger.warning( logger.warning(
"No renewables found in config entry `extendable_carriers`. " "No renewables found in config entry `extendable_carriers`. "
@ -750,18 +750,18 @@ if __name__ == "__main__":
"Falling back to all renewables." "Falling back to all renewables."
) )
conventional_carriers = snakemake.params["electricity"]["conventional_carriers"] conventional_carriers = snakemake.params.electricity["conventional_carriers"]
attach_load( attach_load(
n, n,
snakemake.input.regions, snakemake.input.regions,
snakemake.input.load, snakemake.input.load,
snakemake.input.nuts3_shapes, snakemake.input.nuts3_shapes,
snakemake.params["countries"], snakemake.params.countries,
snakemake.params["scaling_factor"], snakemake.params.scaling_factor,
) )
update_transmission_costs(n, costs, snakemake.params["length_factor"]) update_transmission_costs(n, costs, snakemake.params.length_factor)
conventional_inputs = { conventional_inputs = {
k: v for k, v in snakemake.input.items() if k.startswith("conventional_") k: v for k, v in snakemake.input.items() if k.startswith("conventional_")
@ -772,7 +772,7 @@ if __name__ == "__main__":
ppl, ppl,
conventional_carriers, conventional_carriers,
extendable_carriers, extendable_carriers,
snakemake.params["conventional"], snakemake.params.conventional,
conventional_inputs, conventional_inputs,
) )
@ -782,11 +782,11 @@ if __name__ == "__main__":
snakemake.input, snakemake.input,
renewable_carriers, renewable_carriers,
extendable_carriers, extendable_carriers,
snakemake.params["length_factor"], snakemake.params.length_factor,
) )
if "hydro" in renewable_carriers: if "hydro" in renewable_carriers:
para = snakemake.params["renewable"]["hydro"] para = snakemake.params.renewable["hydro"]
attach_hydro( attach_hydro(
n, n,
costs, costs,
@ -797,7 +797,7 @@ if __name__ == "__main__":
**para, **para,
) )
if "estimate_renewable_capacities" not in snakemake.params["electricity"]: if "estimate_renewable_capacities" not in snakemake.params.electricity:
logger.warning( logger.warning(
"Missing key `estimate_renewable_capacities` under config entry `electricity`. " "Missing key `estimate_renewable_capacities` under config entry `electricity`. "
"In future versions, this will raise an error. " "In future versions, this will raise an error. "
@ -805,18 +805,18 @@ if __name__ == "__main__":
) )
if ( if (
"estimate_renewable_capacities_from_capacity_stats" "estimate_renewable_capacities_from_capacity_stats"
in snakemake.params["electricity"] in snakemake.params.electricity
): ):
estimate_renewable_caps = { estimate_renewable_caps = {
"enable": True, "enable": True,
**snakemake.params["electricity"][ **snakemake.params.electricity[
"estimate_renewable_capacities_from_capacity_stats" "estimate_renewable_capacities_from_capacity_stats"
], ],
} }
else: else:
estimate_renewable_caps = {"enable": False} estimate_renewable_caps = {"enable": False}
else: else:
estimate_renewable_caps = snakemake.params["electricity"][ estimate_renewable_caps = snakemake.params.electricity[
"estimate_renewable_capacities" "estimate_renewable_capacities"
] ]
if "enable" not in estimate_renewable_caps: if "enable" not in estimate_renewable_caps:
@ -832,18 +832,18 @@ if __name__ == "__main__":
"Falling back to whether `renewable_capacities_from_opsd` is non-empty." "Falling back to whether `renewable_capacities_from_opsd` is non-empty."
) )
from_opsd = bool( from_opsd = bool(
snakemake.params["electricity"].get("renewable_capacities_from_opsd", False) snakemake.params.electricity.get("renewable_capacities_from_opsd", False)
) )
estimate_renewable_caps["from_opsd"] = from_opsd estimate_renewable_caps["from_opsd"] = from_opsd
if estimate_renewable_caps["enable"]: if estimate_renewable_caps["enable"]:
if estimate_renewable_caps["from_opsd"]: if estimate_renewable_caps["from_opsd"]:
tech_map = snakemake.params["electricity"]["estimate_renewable_capacities"][ tech_map = snakemake.params.electricity["estimate_renewable_capacities"][
"technology_mapping" "technology_mapping"
] ]
attach_OPSD_renewables(n, tech_map) attach_OPSD_renewables(n, tech_map)
estimate_renewable_capacities( estimate_renewable_capacities(
n, snakemake.params["electricity"], snakemake.params["countries"] n, snakemake.params.electricity, snakemake.params.countries
) )
update_p_nom_max(n) update_p_nom_max(n)

View File

@ -309,7 +309,7 @@ if __name__ == "__main__":
p_nom_max = capacities / max_cap_factor p_nom_max = capacities / max_cap_factor
else: else:
raise AssertionError( raise AssertionError(
'params key `potential` should be one of "simple" ' 'Config key `potential` should be one of "simple" '
f'(default) or "conservative", not "{p_nom_max_meth}"' f'(default) or "conservative", not "{p_nom_max_meth}"'
) )

View File

@ -186,7 +186,7 @@ def get_feature_for_hac(n, buses_i=None, feature=None):
if "offwind" in carriers: if "offwind" in carriers:
carriers.remove("offwind") carriers.remove("offwind")
carriers = np.append( carriers = np.append(
carriers, network.generators.carrier.filter(like="offwind").unique() carriers, n.generators.carrier.filter(like="offwind").unique()
) )
if feature.split("-")[1] == "cap": if feature.split("-")[1] == "cap":
@ -463,26 +463,18 @@ if __name__ == "__main__":
snakemake = mock_snakemake("cluster_network", simpl="", clusters="5") snakemake = mock_snakemake("cluster_network", simpl="", clusters="5")
configure_logging(snakemake) configure_logging(snakemake)
params = snakemake.params
solver_name = snakemake.config["solving"]["solver"]["name"]
n = pypsa.Network(snakemake.input.network) n = pypsa.Network(snakemake.input.network)
focus_weights = snakemake.config.get("focus_weights", None) exclude_carriers = params.cluster_network["exclude_carriers"]
renewable_carriers = pd.Index(
[
tech
for tech in n.generators.carrier.unique()
if tech in snakemake.params["renewable"]
]
)
exclude_carriers = snakemake.params["clustering"]["cluster_network"].get(
"exclude_carriers", []
)
aggregate_carriers = set(n.generators.carrier) - set(exclude_carriers) aggregate_carriers = set(n.generators.carrier) - set(exclude_carriers)
if snakemake.wildcards.clusters.endswith("m"): if snakemake.wildcards.clusters.endswith("m"):
n_clusters = int(snakemake.wildcards.clusters[:-1]) n_clusters = int(snakemake.wildcards.clusters[:-1])
conventional = set(snakemake.params["conventional_carriers"]) aggregate_carriers = set(params.conventional_carriers).intersection(
aggregate_carriers = conventional.intersection(aggregate_carriers) aggregate_carriers
)
elif snakemake.wildcards.clusters == "all": elif snakemake.wildcards.clusters == "all":
n_clusters = len(n.buses) n_clusters = len(n.buses)
else: else:
@ -496,13 +488,12 @@ if __name__ == "__main__":
n, busmap, linemap, linemap, pd.Series(dtype="O") n, busmap, linemap, linemap, pd.Series(dtype="O")
) )
else: else:
line_length_factor = snakemake.params["length_factor"]
Nyears = n.snapshot_weightings.objective.sum() / 8760 Nyears = n.snapshot_weightings.objective.sum() / 8760
hvac_overhead_cost = load_costs( hvac_overhead_cost = load_costs(
snakemake.input.tech_costs, snakemake.input.tech_costs,
snakemake.params["costs"], params.costs,
snakemake.params["max_hours"], params.max_hours,
Nyears, Nyears,
).at["HVAC overhead", "capital_cost"] ).at["HVAC overhead", "capital_cost"]
@ -513,16 +504,16 @@ if __name__ == "__main__":
).all() or x.isnull().all(), "The `potential` configuration option must agree for all renewable carriers, for now!" ).all() or x.isnull().all(), "The `potential` configuration option must agree for all renewable carriers, for now!"
return v return v
aggregation_strategies = snakemake.params["clustering"].get(
"aggregation_strategies", {}
)
# translate str entries of aggregation_strategies to pd.Series functions: # translate str entries of aggregation_strategies to pd.Series functions:
aggregation_strategies = { aggregation_strategies = {
p: {k: getattr(pd.Series, v) for k, v in aggregation_strategies[p].items()} p: {
for p in aggregation_strategies.keys() k: getattr(pd.Series, v)
for k, v in params.aggregation_strategies[p].items()
}
for p in params.aggregation_strategies.keys()
} }
custom_busmap = snakemake.params["custom_busmap"] custom_busmap = params.custom_busmap
if custom_busmap: if custom_busmap:
custom_busmap = pd.read_csv( custom_busmap = pd.read_csv(
snakemake.input.custom_busmap, index_col=0, squeeze=True snakemake.input.custom_busmap, index_col=0, squeeze=True
@ -530,21 +521,18 @@ if __name__ == "__main__":
custom_busmap.index = custom_busmap.index.astype(str) custom_busmap.index = custom_busmap.index.astype(str)
logger.info(f"Imported custom busmap from {snakemake.input.custom_busmap}") logger.info(f"Imported custom busmap from {snakemake.input.custom_busmap}")
cluster_config = snakemake.config.get("clustering", {}).get(
"cluster_network", {}
)
clustering = clustering_for_n_clusters( clustering = clustering_for_n_clusters(
n, n,
n_clusters, n_clusters,
custom_busmap, custom_busmap,
aggregate_carriers, aggregate_carriers,
line_length_factor, params.length_factor,
aggregation_strategies, params.aggregation_strategies,
snakemake.params["solver_name"], solver_name,
cluster_config.get("algorithm", "hac"), params.cluster_network["algorithm"],
cluster_config.get("feature", "solar+onwind-time"), params.cluster_network["feature"],
hvac_overhead_cost, hvac_overhead_cost,
focus_weights, params.focus_weights,
) )
update_p_nom_max(clustering.network) update_p_nom_max(clustering.network)

View File

@ -149,17 +149,17 @@ def simplify_network_to_380(n):
return n, trafo_map return n, trafo_map
def _prepare_connection_costs_per_link(n, costs, renewable_param, length_factor_param): def _prepare_connection_costs_per_link(n, costs, renewable_carriers, length_factor):
if n.links.empty: if n.links.empty:
return {} return {}
connection_costs_per_link = {} connection_costs_per_link = {}
for tech in renewable_param: for tech in renewable_carriers:
if tech.startswith("offwind"): if tech.startswith("offwind"):
connection_costs_per_link[tech] = ( connection_costs_per_link[tech] = (
n.links.length n.links.length
* length_factor_param * length_factor
* ( * (
n.links.underwater_fraction n.links.underwater_fraction
* costs.at[tech + "-connection-submarine", "capital_cost"] * costs.at[tech + "-connection-submarine", "capital_cost"]
@ -175,14 +175,14 @@ def _compute_connection_costs_to_bus(
n, n,
busmap, busmap,
costs, costs,
renewable_param, renewable_carriers,
length_factor_param, length_factor,
connection_costs_per_link=None, connection_costs_per_link=None,
buses=None, buses=None,
): ):
if connection_costs_per_link is None: if connection_costs_per_link is None:
connection_costs_per_link = _prepare_connection_costs_per_link( connection_costs_per_link = _prepare_connection_costs_per_link(
n, costs, renewable_param, length_factor_param n, costs, renewable_carriers, length_factor
) )
if buses is None: if buses is None:
@ -276,10 +276,10 @@ def _aggregate_and_move_components(
def simplify_links( def simplify_links(
n, n,
costs, costs,
renewable_param, renewables,
length_factor_param, length_factor,
p_max_pu_param, p_max_pu,
exclude_carriers_param, exclude_carriers,
output, output,
aggregation_strategies=dict(), aggregation_strategies=dict(),
): ):
@ -333,7 +333,7 @@ def simplify_links(
busmap = n.buses.index.to_series() busmap = n.buses.index.to_series()
connection_costs_per_link = _prepare_connection_costs_per_link( connection_costs_per_link = _prepare_connection_costs_per_link(
n, costs, renewable_param, length_factor_param n, costs, renewables, length_factor
) )
connection_costs_to_bus = pd.DataFrame( connection_costs_to_bus = pd.DataFrame(
0.0, index=n.buses.index, columns=list(connection_costs_per_link) 0.0, index=n.buses.index, columns=list(connection_costs_per_link)
@ -355,8 +355,8 @@ def simplify_links(
n, n,
busmap, busmap,
costs, costs,
renewable_param, renewables,
length_factor_param, length_factor,
connection_costs_per_link, connection_costs_per_link,
buses, buses,
) )
@ -378,8 +378,8 @@ def simplify_links(
/ lengths.sum() / lengths.sum()
* n.links.loc[all_links, "underwater_fraction"] * n.links.loc[all_links, "underwater_fraction"]
), ),
p_max_pu=p_max_pu_param, p_max_pu=p_max_pu,
p_min_pu=-p_max_pu_param, p_min_pu=-p_max_pu,
underground=False, underground=False,
under_construction=False, under_construction=False,
) )
@ -407,7 +407,7 @@ def simplify_links(
connection_costs_to_bus, connection_costs_to_bus,
output, output,
aggregation_strategies=aggregation_strategies, aggregation_strategies=aggregation_strategies,
exclude_carriers=exclude_carriers_param, exclude_carriers=exclude_carriers,
) )
return n, busmap return n, busmap
@ -415,34 +415,29 @@ def simplify_links(
def remove_stubs( def remove_stubs(
n, n,
costs, costs,
renewable_param, renewable_carriers,
length_factor_param, length_factor,
clustering_param, simplify_network,
exclude_carriers_param,
output, output,
aggregation_strategies=dict(), aggregation_strategies=dict(),
): ):
logger.info("Removing stubs") logger.info("Removing stubs")
across_borders = clustering_param["simplify_network"].get( across_borders = simplify_network["remove_stubs_across_borders"]
"remove_stubs_across_borders", True
)
matching_attrs = [] if across_borders else ["country"] matching_attrs = [] if across_borders else ["country"]
busmap = busmap_by_stubs(n, matching_attrs) busmap = busmap_by_stubs(n, matching_attrs)
connection_costs_to_bus = _compute_connection_costs_to_bus( connection_costs_to_bus = _compute_connection_costs_to_bus(
n, busmap, costs, renewable_param, length_factor_param n, busmap, costs, renewable_carriers, length_factor
) )
exclude_carriers = clustering_param["simplify_network"].get("exclude_carriers", [])
_aggregate_and_move_components( _aggregate_and_move_components(
n, n,
busmap, busmap,
connection_costs_to_bus, connection_costs_to_bus,
output, output,
aggregation_strategies=aggregation_strategies, aggregation_strategies=aggregation_strategies,
exclude_carriers=exclude_carriers, exclude_carriers=simplify_network["exclude_carriers"],
) )
return n, busmap return n, busmap
@ -504,32 +499,23 @@ def aggregate_to_substations(n, aggregation_strategies=dict(), buses_i=None):
def cluster( def cluster(
n, n,
n_clusters, n_clusters,
focus_weights_param, focus_weights,
renewable_param, solver_name,
solver_name_param,
algorithm="hac", algorithm="hac",
feature=None, feature=None,
aggregation_strategies=dict(), aggregation_strategies=dict(),
): ):
logger.info(f"Clustering to {n_clusters} buses") logger.info(f"Clustering to {n_clusters} buses")
renewable_carriers = pd.Index(
[
tech
for tech in n.generators.carrier.unique()
if tech.split("-", 2)[0] in renewable_param
]
)
clustering = clustering_for_n_clusters( clustering = clustering_for_n_clusters(
n, n,
n_clusters, n_clusters,
custom_busmap=False, custom_busmap=False,
aggregation_strategies=aggregation_strategies, aggregation_strategies=aggregation_strategies,
solver_name=solver_name_param, solver_name=solver_name,
algorithm=algorithm, algorithm=algorithm,
feature=feature, feature=feature,
focus_weights=focus_weights_param, focus_weights=focus_weights,
) )
return clustering.network, clustering.busmap return clustering.network, clustering.busmap
@ -542,77 +528,69 @@ if __name__ == "__main__":
snakemake = mock_snakemake("simplify_network", simpl="") snakemake = mock_snakemake("simplify_network", simpl="")
configure_logging(snakemake) configure_logging(snakemake)
n = pypsa.Network(snakemake.input.network) params = snakemake.params
solver_name = snakemake.config["solving"]["solver"]["name"]
n = pypsa.Network(snakemake.input.network)
Nyears = n.snapshot_weightings.objective.sum() / 8760
aggregation_strategies = snakemake.params["clustering"].get(
"aggregation_strategies", {}
)
# translate str entries of aggregation_strategies to pd.Series functions: # translate str entries of aggregation_strategies to pd.Series functions:
aggregation_strategies = { aggregation_strategies = {
p: {k: getattr(pd.Series, v) for k, v in aggregation_strategies[p].items()} p: {
for p in aggregation_strategies.keys() k: getattr(pd.Series, v)
for k, v in params.aggregation_strategies[p].items()
}
for p in params.aggregation_strategies.keys()
} }
n, trafo_map = simplify_network_to_380(n) n, trafo_map = simplify_network_to_380(n)
Nyears = n.snapshot_weightings.objective.sum() / 8760
technology_costs = load_costs( technology_costs = load_costs(
snakemake.input.tech_costs, snakemake.input.tech_costs,
snakemake.params["costs"], params.costs,
snakemake.params["max_hours"], params.max_hours,
Nyears, Nyears,
) )
n, simplify_links_map = simplify_links( n, simplify_links_map = simplify_links(
n, n,
technology_costs, technology_costs,
snakemake.params["renewable"], params.renewable_carriers,
snakemake.params["length_factor"], params.length_factor,
snakemake.params["p_max_pu"], params.p_max_pu,
snakemake.params["exclude_carriers"], params.simplify_network["exclude_carriers"],
snakemake.output, snakemake.output,
aggregation_strategies, aggregation_strategies,
) )
busmaps = [trafo_map, simplify_links_map] busmaps = [trafo_map, simplify_links_map]
cluster_param = snakemake.params["clustering"]["simplify_network"] if params.simplify_network["remove_stubs"]:
if cluster_param.get("remove_stubs", True):
n, stub_map = remove_stubs( n, stub_map = remove_stubs(
n, n,
technology_costs, technology_costs,
snakemake.params["renewable"], params.renewable_carriers,
snakemake.params["length_factor"], params.length_factor,
snakemake.params["clustering"], params.simplify_network,
snakemake.params["exclude_carriers"],
snakemake.output, snakemake.output,
aggregation_strategies=aggregation_strategies, aggregation_strategies=aggregation_strategies,
) )
busmaps.append(stub_map) busmaps.append(stub_map)
if cluster_param.get("to_substations", False): if params.simplify_network["to_substations"]:
n, substation_map = aggregate_to_substations(n, aggregation_strategies) n, substation_map = aggregate_to_substations(n, aggregation_strategies)
busmaps.append(substation_map) busmaps.append(substation_map)
# treatment of outliers (nodes without a profile for considered carrier): # treatment of outliers (nodes without a profile for considered carrier):
# all nodes that have no profile of the given carrier are being aggregated to closest neighbor # all nodes that have no profile of the given carrier are being aggregated to closest neighbor
if ( if params.simplify_network["algorithm"] == "hac":
snakemake.config.get("clustering", {}) carriers = params.simplify_network["feature"].split("-")[0].split("+")
.get("cluster_network", {})
.get("algorithm", "hac")
== "hac"
or cluster_param.get("algorithm", "hac") == "hac"
):
carriers = (
cluster_param.get("feature", "solar+onwind-time").split("-")[0].split("+")
)
for carrier in carriers: for carrier in carriers:
buses_i = list( buses_i = list(
set(n.buses.index) - set(n.generators.query("carrier == @carrier").bus) set(n.buses.index) - set(n.generators.query("carrier == @carrier").bus)
) )
logger.info( logger.info(
f"clustering preparaton (hac): aggregating {len(buses_i)} buses of type {carrier}." f"clustering preparation (hac): aggregating {len(buses_i)} buses of type {carrier}."
) )
n, busmap_hac = aggregate_to_substations(n, aggregation_strategies, buses_i) n, busmap_hac = aggregate_to_substations(n, aggregation_strategies, buses_i)
busmaps.append(busmap_hac) busmaps.append(busmap_hac)
@ -621,11 +599,10 @@ if __name__ == "__main__":
n, cluster_map = cluster( n, cluster_map = cluster(
n, n,
int(snakemake.wildcards.simpl), int(snakemake.wildcards.simpl),
snakemake.params["focus_weights"], params.focus_weights,
snakemake.params["renewable"], solver_name,
snakemake.params["solver_name"], params.simplify_network["algorithm"],
cluster_param.get("algorithm", "hac"), params.simplify_network["feature"],
cluster_param.get("feature", None),
aggregation_strategies, aggregation_strategies,
) )
busmaps.append(cluster_map) busmaps.append(cluster_map)