From 4921788a49e63a0a1a909a8419eb56ca2560f3bf Mon Sep 17 00:00:00 2001 From: Daniele Lerede Date: Fri, 27 Sep 2024 16:30:26 +0200 Subject: [PATCH 1/6] get costs_{year}.csv instead of costs.csv --- Snakefile | 2 +- scripts/add_electricity.py | 9 +++-- scripts/build_renewable_profiles.py | 53 ++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/Snakefile b/Snakefile index bc6d6c069..729cfd36a 100644 --- a/Snakefile +++ b/Snakefile @@ -57,7 +57,7 @@ COSTDIR = config["costs_dir"] load_data_paths = get_load_paths_gegis("data", config) if config["enable"].get("retrieve_cost_data", True): - COSTS = "resources/" + RDIR + "costs.csv" + COSTS = "resources/" + RDIR + "costs_{year}.csv".format(year=config["costs"]["year"]) else: COSTS = "data/costs.csv" ATLITE_NPROCESSES = config["atlite"].get("nprocesses", 4) diff --git a/scripts/add_electricity.py b/scripts/add_electricity.py index 3f034a36e..55c9749fc 100755 --- a/scripts/add_electricity.py +++ b/scripts/add_electricity.py @@ -488,7 +488,10 @@ def attach_hydro(n, costs, ppl): ror = ppl.query('technology == "Run-Of-River"') phs = ppl.query('technology == "Pumped Storage"') hydro = ppl.query('technology == "Reservoir"') - bus_id = ppl["bus"] + if snakemake.params.alternative_clustering: + bus_id = ppl["region_id"] + else: + bus_id = ppl["bus"] inflow_idx = ror.index.union(hydro.index) if not inflow_idx.empty: @@ -527,16 +530,12 @@ def attach_hydro(n, costs, ppl): network_buses_to_keep = plants_with_data.index plants_to_keep = plants_with_data.to_numpy() - # hydro_inflow_factor is used to divide the inflow between the various units of each power plant - hydro_inflow_factor = hydro["p_nom"] / hydro.groupby("bus")["p_nom"].transform("sum") - inflow_t = ( inflow.sel(plant=plants_to_keep) .rename({"plant": "name"}) .assign_coords(name=network_buses_to_keep) .transpose("time", "name") .to_pandas() - *hydro_inflow_factor ) if "ror" in carriers and not ror.empty: diff --git a/scripts/build_renewable_profiles.py b/scripts/build_renewable_profiles.py index 808363ac5..1ebf220b4 100644 --- a/scripts/build_renewable_profiles.py +++ b/scripts/build_renewable_profiles.py @@ -356,6 +356,9 @@ def rescale_hydro(plants, runoff, normalize_using_yearly, normalization_year): logger.info("No bus has installed hydro plants, ignoring normalization.") return runoff + if snakemake.params.alternative_clustering: + plants = plants.set_index("shape_id") + years_statistics = normalize_using_yearly.index if isinstance(years_statistics, pd.DatetimeIndex): years_statistics = years_statistics.year @@ -530,6 +533,24 @@ def create_scaling_factor( # the region should be restricted for non-hydro technologies, as the hydro potential is calculated across hydrobasins which may span beyond the region of the country cutout = filter_cutout_region(cutout, regions) + if snakemake.params.alternative_clustering: + regions = gpd.GeoDataFrame( + regions.reset_index() + .groupby("shape_id") + .agg( + { + "x": "mean", + "y": "mean", + "country": "first", + "geometry": "first", + "bus": "first", + } + ) + .reset_index() + .set_index("bus"), + crs=regions.crs, + ) + buses = regions.index func = getattr(cutout, resource.pop("method")) @@ -554,10 +575,17 @@ def create_scaling_factor( # select busbar whose location (p) belongs to at least one hydrobasin geometry # if extendable option is true, all buses are included # otherwise only where hydro powerplants are available are considered - filter_bus_to_consider = regions.index.map( - lambda bus_id: config.get("extendable", False) - | (bus_id in hydro_ppls.bus.values) - ) + if snakemake.params.alternative_clustering: + filter_bus_to_consider = regions.index.map( + lambda bus_id: config.get("extendable", False) + | (bus_id in hydro_ppls.region_id.values) + ) + ### TODO: quickfix. above case and the below case should by unified + if snakemake.params.alternative_clustering == False: + filter_bus_to_consider = regions.index.map( + lambda bus_id: config.get("extendable", False) + | (bus_id in hydro_ppls.bus.values) + ) bus_to_consider = regions.index[filter_bus_to_consider] # identify subset of buses within the hydrobasins @@ -575,10 +603,17 @@ def create_scaling_factor( columns={"x": "lon", "y": "lat", "country": "countries"} ).loc[bus_in_hydrobasins, ["lon", "lat", "countries", "shape_id"]] - resource["plants"]["installed_hydro"] = [ - True if (bus_id in hydro_ppls.bus.values) else False - for bus_id in resource["plants"].index - ] + # TODO: these cases shall be fixed by restructuring the alternative clustering procedure + if snakemake.params.alternative_clustering == False: + resource["plants"]["installed_hydro"] = [ + True if (bus_id in hydro_ppls.bus.values) else False + for bus_id in resource["plants"].index + ] + else: + resource["plants"]["installed_hydro"] = [ + True if (bus_id in hydro_ppls.region_id.values) else False + for bus_id in resource["plants"].shape_id.values + ] # get normalization before executing runoff normalization = None @@ -594,6 +629,8 @@ def create_scaling_factor( else: # otherwise perform the calculations inflow = correction_factor * func(capacity_factor=True, **resource) + if snakemake.params.alternative_clustering: + inflow["plant"] = regions.shape_id.loc[inflow["plant"]].values if "clip_min_inflow" in config: inflow = inflow.where(inflow >= config["clip_min_inflow"], 0) From 1ccc282ef38c9e1e0920ec984517ae8f93ad1b3b Mon Sep 17 00:00:00 2001 From: Daniele Lerede Date: Fri, 27 Sep 2024 16:31:37 +0200 Subject: [PATCH 2/6] get costs_{year}.csv instead of costs.csv --- Snakefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Snakefile b/Snakefile index 729cfd36a..67234d82f 100644 --- a/Snakefile +++ b/Snakefile @@ -57,7 +57,9 @@ COSTDIR = config["costs_dir"] load_data_paths = get_load_paths_gegis("data", config) if config["enable"].get("retrieve_cost_data", True): - COSTS = "resources/" + RDIR + "costs_{year}.csv".format(year=config["costs"]["year"]) + COSTS = ( + "resources/" + RDIR + "costs_{year}.csv".format(year=config["costs"]["year"]) + ) else: COSTS = "data/costs.csv" ATLITE_NPROCESSES = config["atlite"].get("nprocesses", 4) From 0a881871f15d29554e16a50f2a238359f6702b79 Mon Sep 17 00:00:00 2001 From: Daniele Lerede Date: Thu, 3 Oct 2024 18:28:22 +0200 Subject: [PATCH 3/6] remove rule retrieve_cost_data_flexible --- Snakefile | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Snakefile b/Snakefile index 67234d82f..faf81862e 100644 --- a/Snakefile +++ b/Snakefile @@ -407,21 +407,6 @@ if config["enable"].get("retrieve_cost_data", True): run: move(input[0], output[0]) - rule retrieve_cost_data_flexible: - input: - HTTP.remote( - f"raw.githubusercontent.com/PyPSA/technology-data/{config['costs']['version']}/outputs/costs" - + "_{planning_horizons}.csv", - keep_local=True, - ), - output: - costs=COSTDIR + "costs_{planning_horizons}.csv", - resources: - mem_mb=5000, - run: - move(input[0], output[0]) - - rule build_demand_profiles: params: snapshots=config["snapshots"], From 634e18b487bc9aaa54f35405a8780812278b64ad Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:28:47 +0000 Subject: [PATCH 4/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- Snakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Snakefile b/Snakefile index faf81862e..ee044742e 100644 --- a/Snakefile +++ b/Snakefile @@ -407,6 +407,7 @@ if config["enable"].get("retrieve_cost_data", True): run: move(input[0], output[0]) + rule build_demand_profiles: params: snapshots=config["snapshots"], From f783792f1d18e6424ec9189c790e192ad4c304be Mon Sep 17 00:00:00 2001 From: Daniele Lerede Date: Thu, 3 Oct 2024 18:43:09 +0200 Subject: [PATCH 5/6] remove rule retrieve_cost_data_flexible --- Snakefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Snakefile b/Snakefile index ee044742e..faf81862e 100644 --- a/Snakefile +++ b/Snakefile @@ -407,7 +407,6 @@ if config["enable"].get("retrieve_cost_data", True): run: move(input[0], output[0]) - rule build_demand_profiles: params: snapshots=config["snapshots"], From 92b3d65a496bc9572935ca3ad77e282b5f0815cc Mon Sep 17 00:00:00 2001 From: Daniele Lerede Date: Thu, 3 Oct 2024 18:43:35 +0200 Subject: [PATCH 6/6] remove rule retrieve_cost_data_flexible --- Snakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Snakefile b/Snakefile index faf81862e..ee044742e 100644 --- a/Snakefile +++ b/Snakefile @@ -407,6 +407,7 @@ if config["enable"].get("retrieve_cost_data", True): run: move(input[0], output[0]) + rule build_demand_profiles: params: snapshots=config["snapshots"],