From 5006bc487757fe972ff9d912ee5952f068f5182d Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 26 Sep 2023 15:12:39 +0200 Subject: [PATCH] build_biomass_potentials: link to planning_horizons wildcard, interpolate missing years --- doc/release_notes.rst | 4 +++ rules/build_sector.smk | 12 +++++---- scripts/build_biomass_potentials.py | 40 ++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index e343953f..9720b664 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -20,6 +20,10 @@ Upcoming Release * Files extracted from sector-coupled data bundle have been moved from ``data/`` to ``data/sector-bundle``. +* It is now possible to specify years for biomass potentials which do not exist + in the JRC-ENSPRESO database, e.g. 2037. These are linearly interpolated. + +* In pathway mode, the biomass potential is linked to the investment year. **Bugs and Compatibility** diff --git a/rules/build_sector.smk b/rules/build_sector.smk index 10a5f821..47c5a4d9 100644 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -280,15 +280,15 @@ rule build_biomass_potentials: country_shapes=RESOURCES + "country_shapes.geojson", output: biomass_potentials_all=RESOURCES - + "biomass_potentials_all_s{simpl}_{clusters}.csv", - biomass_potentials=RESOURCES + "biomass_potentials_s{simpl}_{clusters}.csv", + + "biomass_potentials_all_s{simpl}_{clusters}_{planning_horizons}.csv", + biomass_potentials=RESOURCES + "biomass_potentials_s{simpl}_{clusters}_{planning_horizons}.csv", threads: 1 resources: mem_mb=1000, log: - LOGS + "build_biomass_potentials_s{simpl}_{clusters}.log", + LOGS + "build_biomass_potentials_s{simpl}_{clusters}_{planning_horizons}.log", benchmark: - BENCHMARKS + "build_biomass_potentials_s{simpl}_{clusters}" + BENCHMARKS + "build_biomass_potentials_s{simpl}_{clusters}_{planning_horizons}" conda: "../envs/environment.yaml" script: @@ -735,7 +735,9 @@ rule prepare_sector_network: dsm_profile=RESOURCES + "dsm_profile_s{simpl}_{clusters}.csv", co2_totals_name=RESOURCES + "co2_totals.csv", co2="data/bundle-sector/eea/UNFCCC_v23.csv", - biomass_potentials=RESOURCES + "biomass_potentials_s{simpl}_{clusters}.csv", + biomass_potentials=RESOURCES + "biomass_potentials_s{simpl}_{clusters}_" + "{}.csv".format(config["biomass"]["year"]) + if config["foresight"] == "overnight" + else RESOURCES + "biomass_potentials_s{simpl}_{clusters}_{planning_horizons}.csv", heat_profile="data/heat_load_profile_BDEW.csv", costs="data/costs_{}.csv".format(config["costs"]["year"]) if config["foresight"] == "overnight" diff --git a/scripts/build_biomass_potentials.py b/scripts/build_biomass_potentials.py index d200a78e..5c1eb31d 100644 --- a/scripts/build_biomass_potentials.py +++ b/scripts/build_biomass_potentials.py @@ -7,9 +7,15 @@ Compute biogas and solid biomass potentials for each clustered model region using data from JRC ENSPRESO. """ +import logging + +logger = logging.getLogger(__name__) import geopandas as gpd +import numpy as np import pandas as pd +AVAILABLE_BIOMASS_YEARS = [2010, 2020, 2030, 2040, 2050] + def build_nuts_population_data(year=2013): pop = pd.read_csv( @@ -208,13 +214,41 @@ if __name__ == "__main__": if "snakemake" not in globals(): from _helpers import mock_snakemake - snakemake = mock_snakemake("build_biomass_potentials", simpl="", clusters="5") + snakemake = mock_snakemake( + "build_biomass_potentials", + simpl="", + clusters="5", + planning_horizons=2050, + ) + overnight = snakemake.config["foresight"] == "overnight" params = snakemake.params.biomass - year = params["year"] + investment_year = int(snakemake.wildcards.planning_horizons) + year = params["year"] if overnight else investment_year scenario = params["scenario"] - enspreso = enspreso_biomass_potentials(year, scenario) + if year > 2050: + logger.info("No biomass potentials for years after 2050, using 2050.") + max_year = max(AVAILABLE_BIOMASS_YEARS) + enspreso = enspreso_biomass_potentials(max_year, scenario) + + elif year not in AVAILABLE_BIOMASS_YEARS: + before = int(np.floor(year / 10) * 10) + after = int(np.ceil(year / 10) * 10) + logger.info( + f"No biomass potentials for {year}, interpolating linearly between {before} and {after}." + ) + + enspreso_before = enspreso_biomass_potentials(before, scenario) + enspreso_after = enspreso_biomass_potentials(after, scenario) + + fraction = (year - before) / (after - before) + + enspreso = enspreso_before + fraction * (enspreso_after - enspreso_before) + + else: + logger.info(f"Using biomass potentials for {year}.") + enspreso = enspreso_biomass_potentials(year, scenario) enspreso = disaggregate_nuts0(enspreso)