From d1b4bd394cce598fc6ef99d257d27e4c29a8f044 Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Wed, 22 Jan 2025 19:02:42 +0100 Subject: [PATCH 01/15] feat: refactor build_heat_source_potentials into build_geothermal_heat_potential and and use ISI Excel output as data source --- scripts/build_geothermal_heat_potential.py | 200 ++++++++++++++++++ .../onshore_region_data.py | 93 -------- scripts/build_heat_source_potentials/run.py | 93 -------- 3 files changed, 200 insertions(+), 186 deletions(-) create mode 100644 scripts/build_geothermal_heat_potential.py delete mode 100755 scripts/build_heat_source_potentials/onshore_region_data.py delete mode 100644 scripts/build_heat_source_potentials/run.py diff --git a/scripts/build_geothermal_heat_potential.py b/scripts/build_geothermal_heat_potential.py new file mode 100644 index 000000000..6a68a1d22 --- /dev/null +++ b/scripts/build_geothermal_heat_potential.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +# SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors +# +# SPDX-License-Identifier: MIT +""" +Build heat source potentials for a given heat source. + +This script maps and aggregates heat source potentials per heat source to `onshore_regions` using `OnshoreRegionData`. +It scales the heat source utilisation potentials to technical potentials by dividing the utilisation potentials by the full load hours of the heat source, also taking into account the energy unit set for the respective source in the config. + + +Relevant Settings +----------------- +.. code:: yaml + sector: + district_heating: + heat_utilisation_potentials: + {heat_source} + + +Inputs +------ +- `resources//regions_onshore.geojson` +- `resources//heat_source_utilisation_potentials/.gpkg` + +Outputs +------- +- `resources//heat_source_technical_potential_{heat_source}_base_s_{clusters}.csv` +""" + +import geopandas as gpd +import pandas as pd +import xarray as xr +from _helpers import set_scenario_config, get_snapshots + +from onshore_region_data import OnshoreRegionData + +ISI_TEMPERATURE_SCENARIOS = { + 65: "low_temperatures", + 85: "high_temperatures", + } +FULL_LOAD_HOURS = 4000 +# 3000 for petrothermal + +PYPSA_EUR_UNIT = "MWh" + +GEOTHERMAL_SOURCE = "Hydrothermal " # trailing space for hydrothermal necessary to get correct column + +def get_unit_conversion_factor( + input_unit: str, + output_unit: str, + unit_scaling: dict = {"Wh": 1, "kWh": 1e3, "MWh": 1e6, "GWh": 1e9, "TWh": 1e12}, +) -> float: + """ + Get the unit conversion factor between two units. + + Parameters + ---------- + input_unit : str + Input unit. Must be one of the keys in `unit_scaling`. + output_unit : str + Output unit. Must be one of the keys in `unit_scaling`. + unit_scaling : dict, optional + Dictionary of unit scaling factors. Default: {"Wh": 1, "kWh": 1e3, "MWh": 1e6, "GWh": 1e9, "TWh": 1e12}. + """ + + if input_unit not in unit_scaling.keys(): + raise ValueError( + f"Input unit {input_unit} not allowed. Must be one of { + unit_scaling.keys()}" + ) + elif output_unit not in unit_scaling.keys(): + raise ValueError( + f"Output unit {output_unit} not allowed. Must be one of { + unit_scaling.keys()}" + ) + + return unit_scaling[input_unit] / unit_scaling[output_unit] + + +def get_heat_source_power( + snapshots: pd.DatetimeIndex, + regions_onshore: gpd.GeoDataFrame, + geothermal_potentials: gpd.GeoDataFrame, + full_load_hours: float, + input_unit: str, + output_unit: str = "MWh", +) -> pd.DataFrame: + """ + Get the heat source power from utilisation potentials. + + Note + ---- + Broadcasts to repeat constant heat source power across snapshots. + + Parameters + ---------- + snapshots : pd.DatetimeIndex + Datetime index of the snapshots. + regions_onshore : gpd.GeoDataFrame + GeoDataFrame of the onshore regions. + heat_source_utilisation_potential : gpd.GeoDataFrame + GeoDataFrame of the heat source utilisation potentials. + column_name : str + Name of the relevant column in `heat_source_utilisation_potentials`. + full_load_hours : float + Full load hours assumed in the utilisation potential computation. Used to scale the utilisation potentials to technical potentials. + input_unit : str + Unit of the utilisation potentials. Used to convert to the output unit. + output_unit : str, optional + Unit of the technical potentials. Default: "MWh". + + Returns + ------- + pd.DataFrame + Heat source power in the onshore regions. Indexed by time and name (onshore region). + """ + + unit_conversion_factor = get_unit_conversion_factor( + input_unit=input_unit, + output_unit=output_unit, + ) + scaling_factor = unit_conversion_factor / full_load_hours + + + heat_potentials_in_lau = gpd.GeoDataFrame(geothermal_potentials, geometry=lau_regions.geometry[geothermal_potentials.index]) + + heat_potentials_in_onshore_regions = gpd.sjoin(heat_potentials_in_lau, regions_onshore, how="inner", predicate="intersects") + heat_potentials_in_onshore_regions_aggregated = heat_potentials_in_onshore_regions.groupby("name").sum(numeric_only=True) + + heat_source_power = pd.DataFrame({t: heat_potentials_in_onshore_regions_aggregated.iloc[:, 0] / scaling_factor for t in snapshots}).T + heat_source_power.index.name = "time" + + return heat_source_power + + +if __name__ == "__main__": + + if "snakemake" not in globals(): + from _helpers import mock_snakemake + + snakemake = mock_snakemake( + "build_heat_source_potentials", + clusters=48, + ) + + set_scenario_config(snakemake) + snapshots: pd.DatetimeIndex = get_snapshots( + snakemake.params.snapshots, snakemake.params.drop_leap_day + ) + + regions_onshore = gpd.read_file(snakemake.input.regions_onshore).to_crs("EPSG:4326") + regions_onshore.index = regions_onshore.name + regions_onshore.drop(columns=["name"], inplace=True) + + lau_regions = gpd.read_file( + f"{snakemake.input.lau_regions}!LAU_RG_01M_2019_3035.geojson", + crs="EPSG:3035", + ).to_crs("EPSG:4326") + lau_regions.index = lau_regions.GISCO_ID + + + this_temperature_scenario = ISI_TEMPERATURE_SCENARIOS[snakemake.params.constant_temperature_celsius] + + isi_heat_potentials = pd.read_excel( + snakemake.input.isi_heat_potentials, + sheet_name="Matching_results", + index_col=0, + header=[0, 1], + ) + input_unit = isi_heat_potentials[ + ( + "Unnamed: 2_level_0", + "Unit", + ) + ][0] + + geothermal_potentials = isi_heat_potentials[ + ( + f"Supply_potentials_{this_temperature_scenario}", + GEOTHERMAL_SOURCE, + ) + ].drop( + index="Total" + ) + + if not geothermal_potentials.index.isin(lau_regions.index).all(): + raise ValueError( + "Some LAU regions in ISI heat potentials are missing from the LAU Regions data." + ) + + heat_source_power = get_heat_source_power( + snapshots=snapshots, + regions_onshore=regions_onshore, + geothermal_potentials=geothermal_potentials, + full_load_hours=FULL_LOAD_HOURS, + input_unit=input_unit, + ) + + heat_source_power.to_csv(snakemake.output[0]) diff --git a/scripts/build_heat_source_potentials/onshore_region_data.py b/scripts/build_heat_source_potentials/onshore_region_data.py deleted file mode 100755 index 3357722df..000000000 --- a/scripts/build_heat_source_potentials/onshore_region_data.py +++ /dev/null @@ -1,93 +0,0 @@ -# SPDX-FileCopyrightText: Contributors to PyPSA-Eur -# -# SPDX-License-Identifier: MIT -""" -Helper class for matching heat source potentials to onshore regions. -""" - -import geopandas as gpd - - -class OnshoreRegionData: - """ - This class is used to map heat potentials to onshore regions. - - Attributes - ---------- - onshore_regions : gpd.GeoDataFrame - GeoDataFrame containing the onshore regions - data : gpd.GeoDataFrame - GeoDataFrame containing the heat potentials - scaling_factor : float - Scaling factor for the heat potentials - """ - - def __init__( - self, - onshore_regions: gpd.GeoDataFrame, - data: gpd.GeoDataFrame, - column_name: str, - scaling_factor: float = 1.0, - ) -> None: - """ - Parameters - ---------- - onshore_regions : gpd.GeoDataFrame - GeoDataFrame containing the onshore regions - data : gpd.GeoDataFrame - GeoDataFrame containing the heat potentials - column_name : str - Column name of the heat potential data in `data` - scaling_factor : float, optional - Scaling factor for the heat potentials, by default 1.0 - """ - - self.onshore_regions = onshore_regions - self.scaling_factor = scaling_factor - self.data = data.to_crs(onshore_regions.crs) - self._column_name = column_name - - self._mapped = False - - @property - def data_in_regions_scaled(self) -> gpd.GeoDataFrame: - """ - Scale the heat potentials and map them to the onshore regions. - - Returns - ------- - gpd.GeoDataFrame - GeoDataFrame containing the scaled heat potentials in the onshore regions - """ - if self._mapped: - return self._scaled_data_in_regions - else: - self._data_in_regions = self._map_to_onshore_regions() - self._mapped = True - return self._scaled_data_in_regions - - def _map_to_onshore_regions(self): - """ - Map the heat potentials to the onshore regions - """ - data_in_regions = gpd.sjoin(self.data, self.onshore_regions, how="right") - - # Initialize an empty list to store the merged GeoDataFrames - ret_val = self.onshore_regions.copy() - ret_val[self._column_name] = ( - data_in_regions.groupby("name")[self._column_name] - .sum() - .reset_index(drop=True) - ) - ret_val = ret_val.set_index("name", drop=True).rename_axis("name")[ - self._column_name - ] - - return ret_val - - @property - def _scaled_data_in_regions(self): - """ - Scale the heat potentials in the onshore regions - """ - return self._data_in_regions * self.scaling_factor diff --git a/scripts/build_heat_source_potentials/run.py b/scripts/build_heat_source_potentials/run.py deleted file mode 100644 index 4126fcc51..000000000 --- a/scripts/build_heat_source_potentials/run.py +++ /dev/null @@ -1,93 +0,0 @@ -# SPDX-FileCopyrightText: Contributors to PyPSA-Eur -# -# SPDX-License-Identifier: MIT -""" -Build heat source potentials for a given heat source. - -This script maps and aggregates heat source potentials per heat source to `onshore_regions` using `OnshoreRegionData`. -It scales the heat source utilisation potentials to technical potentials by dividing the utilisation potentials by the full load hours of the heat source, also taking into account the energy unit set for the respective source in the config. - - -Relevant Settings ------------------ -.. code:: yaml - sector: - district_heating: - heat_utilisation_potentials: - {heat_source} - - -Inputs ------- -- `resources//regions_onshore.geojson` -- `resources//heat_source_utilisation_potentials/.gpkg` - -Outputs -------- -- `resources//heat_source_technical_potential_{heat_source}_base_s_{clusters}.csv` -""" - -import geopandas as gpd -from _helpers import set_scenario_config - -from scripts.build_heat_source_potentials.onshore_region_data import OnshoreRegionData - - -def get_unit_conversion_factor( - input_unit: str, - output_unit: str, - unit_scaling: dict = {"Wh": 1, "kWh": 1e3, "MWh": 1e6, "GWh": 1e9, "TWh": 1e12}, -) -> float: - if input_unit not in unit_scaling.keys(): - raise ValueError( - f"Input unit {input_unit} not allowed. Must be one of {unit_scaling.keys()}" - ) - elif output_unit not in unit_scaling.keys(): - raise ValueError( - f"Output unit {output_unit} not allowed. Must be one of { - unit_scaling.keys() - }" - ) - - return unit_scaling[input_unit] / unit_scaling[output_unit] - - -if __name__ == "__main__": - if "snakemake" not in globals(): - from _helpers import mock_snakemake - - snakemake = mock_snakemake( - "build_heat_source_potentials", - clusters=48, - ) - - set_scenario_config(snakemake) - - regions_onshore = gpd.read_file(snakemake.input.regions_onshore) - heat_source_utilisation_potential = gpd.read_file( - snakemake.input.utilisation_potential - ) - - unit_conversion_factor = get_unit_conversion_factor( - input_unit=snakemake.params.heat_utilisation_potentials[ - snakemake.wildcards.heat_source - ]["unit"], - output_unit="MWh", - ) - scaling_factor = ( - unit_conversion_factor - / snakemake.params.heat_utilisation_potentials[snakemake.wildcards.heat_source][ - "full_load_hours" - ] - ) - - heat_source_technical_potential = OnshoreRegionData( - onshore_regions=regions_onshore, - data=heat_source_utilisation_potential, - column_name=snakemake.params.heat_utilisation_potentials[ - snakemake.wildcards.heat_source - ]["column_name"], - scaling_factor=scaling_factor, - ).data_in_regions_scaled - - heat_source_technical_potential.to_csv(snakemake.output[0]) From e1d095199c213b4004cd58c76f83e5e807c43a38 Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Wed, 22 Jan 2025 19:22:39 +0100 Subject: [PATCH 02/15] feat: remove unnecessary snapshot index --- scripts/build_geothermal_heat_potential.py | 57 ++++++++++------------ scripts/prepare_sector_network.py | 2 +- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/scripts/build_geothermal_heat_potential.py b/scripts/build_geothermal_heat_potential.py index 6a68a1d22..9c4d2ea32 100644 --- a/scripts/build_geothermal_heat_potential.py +++ b/scripts/build_geothermal_heat_potential.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors # # SPDX-License-Identifier: MIT @@ -30,21 +29,21 @@ import geopandas as gpd import pandas as pd -import xarray as xr -from _helpers import set_scenario_config, get_snapshots - -from onshore_region_data import OnshoreRegionData +from _helpers import get_snapshots, set_scenario_config ISI_TEMPERATURE_SCENARIOS = { - 65: "low_temperatures", - 85: "high_temperatures", - } + 65: "low_temperatures", + 85: "high_temperatures", +} FULL_LOAD_HOURS = 4000 # 3000 for petrothermal PYPSA_EUR_UNIT = "MWh" -GEOTHERMAL_SOURCE = "Hydrothermal " # trailing space for hydrothermal necessary to get correct column +GEOTHERMAL_SOURCE = ( + "Hydrothermal " # trailing space for hydrothermal necessary to get correct column +) + def get_unit_conversion_factor( input_unit: str, @@ -66,20 +65,19 @@ def get_unit_conversion_factor( if input_unit not in unit_scaling.keys(): raise ValueError( - f"Input unit {input_unit} not allowed. Must be one of { - unit_scaling.keys()}" + f"Input unit {input_unit} not allowed. Must be one of {unit_scaling.keys()}" ) elif output_unit not in unit_scaling.keys(): raise ValueError( f"Output unit {output_unit} not allowed. Must be one of { - unit_scaling.keys()}" + unit_scaling.keys() + }" ) return unit_scaling[input_unit] / unit_scaling[output_unit] def get_heat_source_power( - snapshots: pd.DatetimeIndex, regions_onshore: gpd.GeoDataFrame, geothermal_potentials: gpd.GeoDataFrame, full_load_hours: float, @@ -122,20 +120,24 @@ def get_heat_source_power( ) scaling_factor = unit_conversion_factor / full_load_hours + heat_potentials_in_lau = gpd.GeoDataFrame( + geothermal_potentials, + geometry=lau_regions.geometry[geothermal_potentials.index], + ) - heat_potentials_in_lau = gpd.GeoDataFrame(geothermal_potentials, geometry=lau_regions.geometry[geothermal_potentials.index]) - - heat_potentials_in_onshore_regions = gpd.sjoin(heat_potentials_in_lau, regions_onshore, how="inner", predicate="intersects") - heat_potentials_in_onshore_regions_aggregated = heat_potentials_in_onshore_regions.groupby("name").sum(numeric_only=True) + heat_potentials_in_onshore_regions = gpd.sjoin( + heat_potentials_in_lau, regions_onshore, how="inner", predicate="intersects" + ) + heat_potentials_in_onshore_regions_aggregated = ( + heat_potentials_in_onshore_regions.groupby("name").sum(numeric_only=True) + ) - heat_source_power = pd.DataFrame({t: heat_potentials_in_onshore_regions_aggregated.iloc[:, 0] / scaling_factor for t in snapshots}).T - heat_source_power.index.name = "time" + heat_source_power = heat_potentials_in_onshore_regions_aggregated / scaling_factor return heat_source_power if __name__ == "__main__": - if "snakemake" not in globals(): from _helpers import mock_snakemake @@ -145,9 +147,6 @@ def get_heat_source_power( ) set_scenario_config(snakemake) - snapshots: pd.DatetimeIndex = get_snapshots( - snakemake.params.snapshots, snakemake.params.drop_leap_day - ) regions_onshore = gpd.read_file(snakemake.input.regions_onshore).to_crs("EPSG:4326") regions_onshore.index = regions_onshore.name @@ -159,8 +158,9 @@ def get_heat_source_power( ).to_crs("EPSG:4326") lau_regions.index = lau_regions.GISCO_ID - - this_temperature_scenario = ISI_TEMPERATURE_SCENARIOS[snakemake.params.constant_temperature_celsius] + this_temperature_scenario = ISI_TEMPERATURE_SCENARIOS[ + snakemake.params.constant_temperature_celsius + ] isi_heat_potentials = pd.read_excel( snakemake.input.isi_heat_potentials, @@ -174,15 +174,13 @@ def get_heat_source_power( "Unit", ) ][0] - + geothermal_potentials = isi_heat_potentials[ ( f"Supply_potentials_{this_temperature_scenario}", GEOTHERMAL_SOURCE, ) - ].drop( - index="Total" - ) + ].drop(index="Total") if not geothermal_potentials.index.isin(lau_regions.index).all(): raise ValueError( @@ -190,7 +188,6 @@ def get_heat_source_power( ) heat_source_power = get_heat_source_power( - snapshots=snapshots, regions_onshore=regions_onshore, geothermal_potentials=geothermal_potentials, full_load_hours=FULL_LOAD_HOURS, diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 3593b0bfe..51eb7979d 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -2161,7 +2161,7 @@ def add_heat( else costs.at[costs_name_heat_pump, "efficiency"] ) - if heat_source in snakemake.params.heat_utilisation_potentials: + if heat_source in snakemake.params.limited_heat_sources: # get potential p_max_source = pd.read_csv( snakemake.input[heat_source], From 8caf588712e9369454bc62f3e54f651e4f7df313 Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Wed, 22 Jan 2025 19:22:54 +0100 Subject: [PATCH 03/15] chore: refactor accordingly --- config/config.default.yaml | 9 +--- rules/build_sector.smk | 50 +++++++++++-------- scripts/build_cop_profiles/run.py | 4 +- ...direct_heat_source_utilisation_profiles.py | 4 +- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index ffebff647..37541bce9 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -480,16 +480,9 @@ sector: heat_exchanger_pinch_point_temperature_difference: 5 #K isentropic_compressor_efficiency: 0.8 heat_loss: 0.0 - heat_utilisation_potentials: + limited_heat_sources: geothermal: - # activate for 85C hydrothermal - # key: hydrothermal_85 - # constant_temperature_celsius: 85 - key: hydrothermal_65 constant_temperature_celsius: 65 - column_name: Energy_TWh - unit: TWh - full_load_hours: 4000 direct_utilisation_heat_sources: - geothermal heat_pump_sources: diff --git a/rules/build_sector.smk b/rules/build_sector.smk index 087ed1fb0..46327cd0d 100755 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -284,26 +284,31 @@ rule build_central_heating_temperature_profiles: "../scripts/build_central_heating_temperature_profiles/run.py" -rule build_heat_source_potentials: +rule build_geothermal_heat_potential: params: - heat_utilisation_potentials=config_provider( - "sector", "district_heating", "heat_utilisation_potentials" - ), + drop_leap_day=config_provider("enable", "drop_leap_day"), + countries=config_provider("countries"), + constant_temperature_celsius=config_provider("sector", "district_heating", "limited_heat_sources", "geothermal", "constant_temperature_celsius"), input: - utilisation_potential="data/heat_source_utilisation_potentials/{heat_source}.gpkg", + isi_heat_potentials=storage("https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/12/Results_DH_Matching_Cluster.xlsx", keep_local=True), regions_onshore=resources("regions_onshore_base_s_{clusters}.geojson"), + lau_regions=storage( + "https://gisco-services.ec.europa.eu/distribution/v2/lau/download/ref-lau-2019-01m.geojson.zip", + keep_local=True, + ) output: - resources("heat_source_potential_{heat_source}_base_s_{clusters}.csv"), + heat_source_power=resources("heat_source_power_geothermal_base_s_{clusters}.csv"), resources: mem_mb=2000, log: - logs("build_heat_source_potentials_{heat_source}_s_{clusters}.log"), + logs("build_heat_source_potentials_geothermal_s_{clusters}.log"), benchmark: - benchmarks("build_heat_source_potentials/{heat_source}_s_{clusters}") + benchmarks("build_heat_source_potentials/geothermal_s_{clusters}") conda: "../envs/environment.yaml" script: - "../scripts/build_heat_source_potentials/run.py" + "../scripts/build_geothermal_heat_potential.py" + rule build_cop_profiles: @@ -318,8 +323,8 @@ rule build_cop_profiles: "sector", "district_heating", "heat_pump_cop_approximation" ), heat_pump_sources=config_provider("sector", "heat_pump_sources"), - heat_utilisation_potentials=config_provider( - "sector", "district_heating", "heat_utilisation_potentials" + limited_heat_sources=config_provider( + "sector", "district_heating", "limited_heat_sources" ), snapshots=config_provider("snapshots"), input: @@ -351,8 +356,8 @@ rule build_direct_heat_source_utilisation_profiles: direct_utilisation_heat_sources=config_provider( "sector", "district_heating", "direct_utilisation_heat_sources" ), - heat_utilisation_potentials=config_provider( - "sector", "district_heating", "heat_utilisation_potentials" + limited_heat_sources=config_provider( + "sector", "district_heating", "limited_heat_sources" ), snapshots=config_provider("snapshots"), input: @@ -1062,17 +1067,18 @@ rule build_egs_potentials: "../scripts/build_egs_potentials.py" -def input_heat_source_potentials(w): +def input_heat_source_power(w): return { heat_source_name: resources( - "heat_source_potential_" + heat_source_name + "_base_s_{clusters}.csv" + "heat_source_power_" + heat_source_name + "_base_s_{clusters}.csv" ) for heat_source_name in config_provider( - "sector", "district_heating", "heat_utilisation_potentials" - )(w).keys() + "sector", "heat_pump_sources", "urban central")(w) if heat_source_name - in config_provider("sector", "heat_pump_sources", "urban central")(w) + in config_provider( + "sector", "district_heating", "limited_heat_sources" + )(w).keys() } @@ -1100,15 +1106,15 @@ rule prepare_sector_network: heat_pump_sources=config_provider("sector", "heat_pump_sources"), heat_systems=config_provider("sector", "heat_systems"), energy_totals_year=config_provider("energy", "energy_totals_year"), - heat_utilisation_potentials=config_provider( - "sector", "district_heating", "heat_utilisation_potentials" - ), direct_utilisation_heat_sources=config_provider( "sector", "district_heating", "direct_utilisation_heat_sources" ), + limited_heat_sources=config_provider( + "sector", "district_heating", "limited_heat_sources" + ), input: unpack(input_profile_offwind), - unpack(input_heat_source_potentials), + unpack(input_heat_source_power), **rules.cluster_gas_network.output, **rules.build_gas_input_locations.output, snapshot_weightings=resources( diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 4398bf4fb..855b30ed1 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -114,9 +114,9 @@ def get_cop( f"temp_{heat_source.replace('ground', 'soil')}_total" ] ) - elif heat_source in snakemake.params.heat_utilisation_potentials.keys(): + elif heat_source in snakemake.params.limited_heat_sources.keys(): source_inlet_temperature_celsius = ( - snakemake.params.heat_utilisation_potentials[heat_source][ + snakemake.params.limited_heat_sources[heat_source][ "constant_temperature_celsius" ] ) diff --git a/scripts/build_direct_heat_source_utilisation_profiles.py b/scripts/build_direct_heat_source_utilisation_profiles.py index cfe3bc5a5..cd90b922f 100644 --- a/scripts/build_direct_heat_source_utilisation_profiles.py +++ b/scripts/build_direct_heat_source_utilisation_profiles.py @@ -48,8 +48,8 @@ def get_source_temperature(heat_source_key: str): If the heat source is unknown (not in `config`). """ - if heat_source_key in snakemake.params.heat_utilisation_potentials.keys(): - return snakemake.params.heat_utilisation_potentials[heat_source_key][ + if heat_source_key in snakemake.params.limited_heat_sources.keys(): + return snakemake.params.limited_heat_sources[heat_source_key][ "constant_temperature_celsius" ] else: From c3174eba014544c116194eca4839a29f32efc4be Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Thu, 23 Jan 2025 14:32:58 +0100 Subject: [PATCH 04/15] feat: fix scaling factor --- scripts/build_geothermal_heat_potential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_geothermal_heat_potential.py b/scripts/build_geothermal_heat_potential.py index 9c4d2ea32..696f2b71f 100644 --- a/scripts/build_geothermal_heat_potential.py +++ b/scripts/build_geothermal_heat_potential.py @@ -132,7 +132,7 @@ def get_heat_source_power( heat_potentials_in_onshore_regions.groupby("name").sum(numeric_only=True) ) - heat_source_power = heat_potentials_in_onshore_regions_aggregated / scaling_factor + heat_source_power = heat_potentials_in_onshore_regions_aggregated * scaling_factor return heat_source_power From 78af02f8c378d0b4d28505eee11939c7ec29586c Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Mon, 27 Jan 2025 10:44:10 +0100 Subject: [PATCH 05/15] feat: remove obsolete retrieve --- rules/retrieve.smk | 19 ------- ...ieve_heat_source_utilisation_potentials.py | 56 ------------------- 2 files changed, 75 deletions(-) delete mode 100644 scripts/retrieve_heat_source_utilisation_potentials.py diff --git a/rules/retrieve.smk b/rules/retrieve.smk index 6bbed4fa0..46c9e102f 100755 --- a/rules/retrieve.smk +++ b/rules/retrieve.smk @@ -650,25 +650,6 @@ if config["enable"]["retrieve"]: script: "../scripts/retrieve_osm_boundaries.py" - -if config["enable"]["retrieve"]: - - rule retrieve_heat_source_utilisation_potentials: - params: - heat_source="{heat_source}", - heat_utilisation_potentials=config_provider( - "sector", "district_heating", "heat_utilisation_potentials" - ), - log: - "logs/retrieve_heat_source_potentials_{heat_source}.log", - resources: - mem_mb=500, - output: - "data/heat_source_utilisation_potentials/{heat_source}.gpkg", - script: - "../scripts/retrieve_heat_source_utilisation_potentials.py" - - if config["enable"]["retrieve"]: rule retrieve_jrc_ardeco: diff --git a/scripts/retrieve_heat_source_utilisation_potentials.py b/scripts/retrieve_heat_source_utilisation_potentials.py deleted file mode 100644 index c5a5af59b..000000000 --- a/scripts/retrieve_heat_source_utilisation_potentials.py +++ /dev/null @@ -1,56 +0,0 @@ -# SPDX-FileCopyrightText: Contributors to PyPSA-Eur -# -# SPDX-License-Identifier: MIT -""" -Retrieve heat source utilisation potentials from Fraunhofer Fordatis. - -Source ------- -Manz et al. 2024: "Spatial analysis of renewable and excess heat potentials for climate-neutral district heating in Europe", Renewable Energy, vol. 224, no. 120111, https://doi.org/10.1016/j.renene.2024.120111 - -Relevant Settings ------------------ -.. code:: yaml - sector: - district_heating: - heat_utilisation_potentials: - -Outputs ------- -- `resources//heat_source_utilisation_potentials/.gpkg` -""" - -import logging -from pathlib import Path - -from _helpers import configure_logging, progress_retrieve, set_scenario_config - -logger = logging.getLogger(__name__) - -if __name__ == "__main__": - if "snakemake" not in globals(): - from _helpers import mock_snakemake - - snakemake = mock_snakemake("retrieve_heat_source_utilisation_potentials") - rootpath = ".." - else: - rootpath = "." - configure_logging(snakemake) - set_scenario_config(snakemake) - - # license: https://creativecommons.org/licenses/by/4.0/ - # download the data in url - heat_source = snakemake.params["heat_source"] - filepath = Path(snakemake.output[0]) - if not filepath.parent.exists(): - filepath.parent.mkdir(parents=True) - - url = f"https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/10/{snakemake.params.heat_utilisation_potentials[heat_source]['key']}.gpkg" - - logger.info( - f"Downloading heat source utilisation potential data for {heat_source} from '{url}'." - ) - disable_progress = snakemake.config["run"].get("disable_progressbar", False) - progress_retrieve(url, filepath, disable=disable_progress) - - logger.info(f"Data available at at {filepath}") From 6efd49c06946ff156e4007dbd542021f15ec31b1 Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Mon, 27 Jan 2025 10:56:42 +0100 Subject: [PATCH 06/15] docs: update docs --- doc/configtables/sector.csv | 7 +-- scripts/build_geothermal_heat_potential.py | 56 +++++++++++++--------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/doc/configtables/sector.csv b/doc/configtables/sector.csv index ba98adee0..ac0392acd 100644 --- a/doc/configtables/sector.csv +++ b/doc/configtables/sector.csv @@ -23,14 +23,9 @@ district_heating,--,,`prepare_sector_network.py ) should be used, +-- limited_heat_sources,--,Dictionary with names of limited heat sources (not air) for which data by Fraunhofer ISI (`Manz et al. 2024 ) is used, -- -- geothermal,-,Name of the heat source. Must be the same as in ``heat_pump_sources``, --- -- -- key,-,string used to complete URL for data download - e.g. `geothermal_65` or `geothermal_85`","i.e file names in `Fordatis `, -- -- -- constant_temperature_celsius,°C,heat source temperature, --- -- -- column_name,-,name of the data column in retrieved GeoDataFrame, - --- -- -- unit,-,unit of heat source potential must be in (K/M/G/T)Wh, --- -- -- full_load_hours,h,assumed full-load hours in Manz et al. (used to scale from utilisation to technical potential), -- direct_utilisation_heat_sources,--,List of heat sources for direct heat utilisation in district heating. Must be in the keys of `heat_utilisation_potentials` (e.g. ``geothermal``), -- heat_pump_sources,--,, -- -- urban central,--,List of heat sources for heat pumps in urban central heating, diff --git a/scripts/build_geothermal_heat_potential.py b/scripts/build_geothermal_heat_potential.py index 696f2b71f..609923831 100644 --- a/scripts/build_geothermal_heat_potential.py +++ b/scripts/build_geothermal_heat_potential.py @@ -4,7 +4,7 @@ """ Build heat source potentials for a given heat source. -This script maps and aggregates heat source potentials per heat source to `onshore_regions` using `OnshoreRegionData`. +This script maps and aggregates geothermal heat source potentials `onshore_regions`. Input data is provided on LAU-level and is aggregated to the onshore regions. It scales the heat source utilisation potentials to technical potentials by dividing the utilisation potentials by the full load hours of the heat source, also taking into account the energy unit set for the respective source in the config. @@ -13,23 +13,32 @@ .. code:: yaml sector: district_heating: - heat_utilisation_potentials: - {heat_source} - + limited_heat_sources: + geothermal: + constant_temperature_celsius Inputs ------ - `resources//regions_onshore.geojson` -- `resources//heat_source_utilisation_potentials/.gpkg` +- `resources//lau_regions.geojson` +- `resources//isi_heat_potentials.xlsx` Outputs ------- - `resources//heat_source_technical_potential_{heat_source}_base_s_{clusters}.csv` + +Raises +------ +- ValueError if some LAU regions in ISI heat potentials are missing from the LAU Regions data. + +Source +---------- +- Manz et al. 2024: "Spatial analysis of renewable and excess heat potentials for climate-neutral district heating in Europe", Renewable Energy, vol. 224, no. 120111, https://doi.org/10.1016/j.renene.2024.120111 """ import geopandas as gpd import pandas as pd -from _helpers import get_snapshots, set_scenario_config +from _helpers import set_scenario_config ISI_TEMPERATURE_SCENARIOS = { 65: "low_temperatures", @@ -79,13 +88,13 @@ def get_unit_conversion_factor( def get_heat_source_power( regions_onshore: gpd.GeoDataFrame, - geothermal_potentials: gpd.GeoDataFrame, + supply_potentials: gpd.GeoDataFrame, full_load_hours: float, input_unit: str, output_unit: str = "MWh", ) -> pd.DataFrame: """ - Get the heat source power from utilisation potentials. + Get the heat source power from supply potentials. Note ---- @@ -93,25 +102,21 @@ def get_heat_source_power( Parameters ---------- - snapshots : pd.DatetimeIndex - Datetime index of the snapshots. regions_onshore : gpd.GeoDataFrame GeoDataFrame of the onshore regions. - heat_source_utilisation_potential : gpd.GeoDataFrame - GeoDataFrame of the heat source utilisation potentials. - column_name : str - Name of the relevant column in `heat_source_utilisation_potentials`. + supply_potentials : gpd.GeoDataFrame + GeoDataFrame of the heat source supply potentials. full_load_hours : float - Full load hours assumed in the utilisation potential computation. Used to scale the utilisation potentials to technical potentials. + Full load hours assumed in the supply potential computation. Used to scale the supply potentials to technical potentials. input_unit : str - Unit of the utilisation potentials. Used to convert to the output unit. + Unit of the supply potentials. Used to convert to the output unit. output_unit : str, optional Unit of the technical potentials. Default: "MWh". Returns ------- pd.DataFrame - Heat source power in the onshore regions. Indexed by time and name (onshore region). + Heat source power in the onshore regions. Indexed by name (onshore region). """ unit_conversion_factor = get_unit_conversion_factor( @@ -121,8 +126,8 @@ def get_heat_source_power( scaling_factor = unit_conversion_factor / full_load_hours heat_potentials_in_lau = gpd.GeoDataFrame( - geothermal_potentials, - geometry=lau_regions.geometry[geothermal_potentials.index], + supply_potentials, + geometry=lau_regions.geometry[supply_potentials.index], ) heat_potentials_in_onshore_regions = gpd.sjoin( @@ -148,20 +153,24 @@ def get_heat_source_power( set_scenario_config(snakemake) + # get onshore regions and index them by region name regions_onshore = gpd.read_file(snakemake.input.regions_onshore).to_crs("EPSG:4326") regions_onshore.index = regions_onshore.name regions_onshore.drop(columns=["name"], inplace=True) + # get LAU regions and index them by LAU-ID lau_regions = gpd.read_file( f"{snakemake.input.lau_regions}!LAU_RG_01M_2019_3035.geojson", crs="EPSG:3035", ).to_crs("EPSG:4326") lau_regions.index = lau_regions.GISCO_ID + # temperature scenario that was assumed by Manz et al. when computing potentials is 65C (default) or 85C this_temperature_scenario = ISI_TEMPERATURE_SCENARIOS[ snakemake.params.constant_temperature_celsius ] + # get heat potentials, index them by LAU-ID and get the geothermal potentials isi_heat_potentials = pd.read_excel( snakemake.input.isi_heat_potentials, sheet_name="Matching_results", @@ -174,22 +183,23 @@ def get_heat_source_power( "Unit", ) ][0] - - geothermal_potentials = isi_heat_potentials[ + geothermal_supply_potentials = isi_heat_potentials[ ( f"Supply_potentials_{this_temperature_scenario}", GEOTHERMAL_SOURCE, ) ].drop(index="Total") - if not geothermal_potentials.index.isin(lau_regions.index).all(): + # check if all LAU regions in ISI heat potentials are present in LAU Regions data + if not geothermal_supply_potentials.index.isin(lau_regions.index).all(): raise ValueError( "Some LAU regions in ISI heat potentials are missing from the LAU Regions data." ) + # get heat source power by mapping heat potentials to onshore regions and scaling to from supply potentials to technical potentials heat_source_power = get_heat_source_power( regions_onshore=regions_onshore, - geothermal_potentials=geothermal_potentials, + supply_potentials=geothermal_supply_potentials, full_load_hours=FULL_LOAD_HOURS, input_unit=input_unit, ) From 2b1e3b60adeebdfc1a76697abc0efbf989b6de2f Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Mon, 27 Jan 2025 10:59:16 +0100 Subject: [PATCH 07/15] docs: update release notes --- doc/release_notes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 3d4208088..f8a1173db 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -11,6 +11,8 @@ Release Notes Upcoming Release ================ +* Bugfix: Geothermal heat potentials are now restricted to those in close proximity to future district heating areas as projected by Manz et al. 2024. Includes a refactoring change: Building of generic technical potentials from heat utilisation potentials was changed to specific computation of geothermal heat potentials. + * Bugfix: The missing lifetime attribute was added to hydrogen steel tanks, which is important for pathway planning. * Bugfix: The length factor on the transmission lines haversine length was From 3080d25ce92f92b62047d34bf9a807f8ad65cbb0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:09:07 +0000 Subject: [PATCH 08/15] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- rules/build_sector.smk | 29 ++++++++++++++++++++--------- rules/retrieve.smk | 1 + 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/rules/build_sector.smk b/rules/build_sector.smk index 644b0feda..489c6118f 100755 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -294,16 +294,27 @@ rule build_geothermal_heat_potential: params: drop_leap_day=config_provider("enable", "drop_leap_day"), countries=config_provider("countries"), - constant_temperature_celsius=config_provider("sector", "district_heating", "limited_heat_sources", "geothermal", "constant_temperature_celsius"), + constant_temperature_celsius=config_provider( + "sector", + "district_heating", + "limited_heat_sources", + "geothermal", + "constant_temperature_celsius", + ), input: - isi_heat_potentials=storage("https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/12/Results_DH_Matching_Cluster.xlsx", keep_local=True), + isi_heat_potentials=storage( + "https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/12/Results_DH_Matching_Cluster.xlsx", + keep_local=True, + ), regions_onshore=resources("regions_onshore_base_s_{clusters}.geojson"), lau_regions=storage( "https://gisco-services.ec.europa.eu/distribution/v2/lau/download/ref-lau-2019-01m.geojson.zip", keep_local=True, - ) + ), output: - heat_source_power=resources("heat_source_power_geothermal_base_s_{clusters}.csv"), + heat_source_power=resources( + "heat_source_power_geothermal_base_s_{clusters}.csv" + ), resources: mem_mb=2000, log: @@ -316,7 +327,6 @@ rule build_geothermal_heat_potential: "../scripts/build_geothermal_heat_potential.py" - rule build_cop_profiles: params: heat_pump_sink_T_decentral_heating=config_provider( @@ -1090,11 +1100,12 @@ def input_heat_source_power(w): "heat_source_power_" + heat_source_name + "_base_s_{clusters}.csv" ) for heat_source_name in config_provider( - "sector", "heat_pump_sources", "urban central")(w) + "sector", "heat_pump_sources", "urban central" + )(w) if heat_source_name - in config_provider( - "sector", "district_heating", "limited_heat_sources" - )(w).keys() + in config_provider("sector", "district_heating", "limited_heat_sources")( + w + ).keys() } diff --git a/rules/retrieve.smk b/rules/retrieve.smk index 46c9e102f..b476aa7d1 100755 --- a/rules/retrieve.smk +++ b/rules/retrieve.smk @@ -650,6 +650,7 @@ if config["enable"]["retrieve"]: script: "../scripts/retrieve_osm_boundaries.py" + if config["enable"]["retrieve"]: rule retrieve_jrc_ardeco: From 2c45c8e1896b772f3e0126407db91a4aa7077530 Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Tue, 11 Feb 2025 13:34:31 +0100 Subject: [PATCH 09/15] feat: use retrieve separate retrieve rules --- rules/build_sector.smk | 7 ++----- rules/retrieve.smk | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/rules/build_sector.smk b/rules/build_sector.smk index 644b0feda..da4dcae2c 100755 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -296,12 +296,9 @@ rule build_geothermal_heat_potential: countries=config_provider("countries"), constant_temperature_celsius=config_provider("sector", "district_heating", "limited_heat_sources", "geothermal", "constant_temperature_celsius"), input: - isi_heat_potentials=storage("https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/12/Results_DH_Matching_Cluster.xlsx", keep_local=True), + isi_heat_potentials="data/isi_heat_utilisation_potentials.xlsx", regions_onshore=resources("regions_onshore_base_s_{clusters}.geojson"), - lau_regions=storage( - "https://gisco-services.ec.europa.eu/distribution/v2/lau/download/ref-lau-2019-01m.geojson.zip", - keep_local=True, - ) + lau_regions="data/lau_regions.geojson", output: heat_source_power=resources("heat_source_power_geothermal_base_s_{clusters}.csv"), resources: diff --git a/rules/retrieve.smk b/rules/retrieve.smk index 46c9e102f..16a647322 100755 --- a/rules/retrieve.smk +++ b/rules/retrieve.smk @@ -649,6 +649,39 @@ if config["enable"]["retrieve"]: "../envs/environment.yaml" script: "../scripts/retrieve_osm_boundaries.py" + + rule retrieve_geothermal_heat_utilisation_potentials: + input: + isi_heat_potentials=storage("https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/12/Results_DH_Matching_Cluster.xlsx", keep_local=True), + output: + "data/isi_heat_utilisation_potentials.xlsx", + log: + "logs/retrieve_geothermal_heat_utilisation_potentials.log", + threads: 1 + conda: + "../envs/environment.yaml" + retries: 2 + run: + move(input[0], output[0]) + + rule retrieve_lau_regions: + input: + lau_regions=storage( + "https://gisco-services.ec.europa.eu/distribution/v2/lau/download/ref-lau-2019-01m.geojson.zip", + keep_local=True, + ) + output: + lau_regions="data/lau_regions.geojson", + log: "logs/retrieve_lau_regions.log", + threads: 1 + conda: + "../envs/environment.yaml" + retries: 2 + run: + move(input[0], output[0]) + + + if config["enable"]["retrieve"]: From b4b1a0227e0f3b0ac22ba8d186e88cb1a12fb7c8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 12:37:54 +0000 Subject: [PATCH 10/15] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- rules/retrieve.smk | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rules/retrieve.smk b/rules/retrieve.smk index e3c533013..a8e864bed 100755 --- a/rules/retrieve.smk +++ b/rules/retrieve.smk @@ -649,10 +649,13 @@ if config["enable"]["retrieve"]: "../envs/environment.yaml" script: "../scripts/retrieve_osm_boundaries.py" - + rule retrieve_geothermal_heat_utilisation_potentials: input: - isi_heat_potentials=storage("https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/12/Results_DH_Matching_Cluster.xlsx", keep_local=True), + isi_heat_potentials=storage( + "https://fordatis.fraunhofer.de/bitstream/fordatis/341.3/12/Results_DH_Matching_Cluster.xlsx", + keep_local=True, + ), output: "data/isi_heat_utilisation_potentials.xlsx", log: @@ -667,12 +670,13 @@ if config["enable"]["retrieve"]: rule retrieve_lau_regions: input: lau_regions=storage( - "https://gisco-services.ec.europa.eu/distribution/v2/lau/download/ref-lau-2019-01m.geojson.zip", - keep_local=True, - ) + "https://gisco-services.ec.europa.eu/distribution/v2/lau/download/ref-lau-2019-01m.geojson.zip", + keep_local=True, + ), output: lau_regions="data/lau_regions.geojson", - log: "logs/retrieve_lau_regions.log", + log: + "logs/retrieve_lau_regions.log", threads: 1 conda: "../envs/environment.yaml" @@ -681,9 +685,6 @@ if config["enable"]["retrieve"]: move(input[0], output[0]) - - - if config["enable"]["retrieve"]: rule retrieve_jrc_ardeco: From 15aa6543236cb8a6d09384d41936f2bc904415ea Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Tue, 11 Feb 2025 13:38:41 +0100 Subject: [PATCH 11/15] feat: remove conda env from new retrieve rules --- rules/retrieve.smk | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rules/retrieve.smk b/rules/retrieve.smk index e3c533013..b78a4865e 100755 --- a/rules/retrieve.smk +++ b/rules/retrieve.smk @@ -658,8 +658,6 @@ if config["enable"]["retrieve"]: log: "logs/retrieve_geothermal_heat_utilisation_potentials.log", threads: 1 - conda: - "../envs/environment.yaml" retries: 2 run: move(input[0], output[0]) @@ -674,8 +672,6 @@ if config["enable"]["retrieve"]: lau_regions="data/lau_regions.geojson", log: "logs/retrieve_lau_regions.log", threads: 1 - conda: - "../envs/environment.yaml" retries: 2 run: move(input[0], output[0]) From c0161a7c11f1ba520eb986ec9103c630f2b775dc Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Wed, 12 Feb 2025 12:05:35 +0100 Subject: [PATCH 12/15] fix file names --- rules/build_sector.smk | 2 +- rules/retrieve.smk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/build_sector.smk b/rules/build_sector.smk index d80b4ef0b..6837a0f55 100755 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -290,7 +290,7 @@ rule build_geothermal_heat_potential: input: isi_heat_potentials="data/isi_heat_utilisation_potentials.xlsx", regions_onshore=resources("regions_onshore_base_s_{clusters}.geojson"), - lau_regions="data/lau_regions.geojson", + lau_regions="data/lau_regions.zip", output: heat_source_power=resources( "heat_source_power_geothermal_base_s_{clusters}.csv" diff --git a/rules/retrieve.smk b/rules/retrieve.smk index b78a4865e..faa7c5b5e 100755 --- a/rules/retrieve.smk +++ b/rules/retrieve.smk @@ -669,7 +669,7 @@ if config["enable"]["retrieve"]: keep_local=True, ) output: - lau_regions="data/lau_regions.geojson", + lau_regions="data/lau_regions.zip", log: "logs/retrieve_lau_regions.log", threads: 1 retries: 2 From 2afb3ad87ab261b5132700cd2a5c50c9fef8cf74 Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Wed, 12 Feb 2025 12:05:42 +0100 Subject: [PATCH 13/15] fix config passing --- scripts/prepare_sector_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 9144cbd3c..dd1d6db42 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -5209,7 +5209,7 @@ def add_enhanced_geothermal( floor_area_file=snakemake.input.floor_area, heat_source_profile_files={ source: snakemake.input[source] - for source in snakemake.params.heat_utilisation_potentials + for source in snakemake.params.limited_heat_sources if source in snakemake.input.keys() }, params=snakemake.params, From 08427e224e41036234c790a013538204ab0beb57 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:07:06 +0000 Subject: [PATCH 14/15] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- rules/retrieve.smk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/retrieve.smk b/rules/retrieve.smk index 6648b80f5..6641086e3 100755 --- a/rules/retrieve.smk +++ b/rules/retrieve.smk @@ -676,7 +676,8 @@ if config["enable"]["retrieve"]: log: "logs/retrieve_lau_regions.log", lau_regions="data/lau_regions.zip", - log: "logs/retrieve_lau_regions.log", + log: + "logs/retrieve_lau_regions.log", threads: 1 retries: 2 run: From bc011db63e592b02d428525eb0c8d3bc779f5413 Mon Sep 17 00:00:00 2001 From: Amos Schledorn Date: Mon, 17 Feb 2025 11:05:27 +0100 Subject: [PATCH 15/15] style: remove snakemake access in add_heat --- scripts/prepare_sector_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index dd1d6db42..4690acf59 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -2499,7 +2499,7 @@ def add_heat( else costs.at[costs_name_heat_pump, "efficiency"] ) - if heat_source in snakemake.params.limited_heat_sources: + if heat_source in params.limited_heat_sources: # get potential p_max_source = pd.read_csv( heat_source_profile_files[heat_source],