Merge branch 'master' into jrc-idees-2020

This commit is contained in:
lisazeyen 2024-07-22 21:43:03 +02:00 committed by GitHub
commit 8f2cea4d93
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 286 additions and 185 deletions

39
.github/workflows/update-fixed-env.yaml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Fixed Environment YAML Monitor
on:
push:
branches:
- master
paths:
- 'env/environment.yaml'
jobs:
update_environment_fixed:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup micromamba
uses: mamba-org/setup-micromamba@v1
with:
micromamba-version: latest
environment-file: envs/environment.yaml
log-level: debug
init-shell: bash
cache-environment: true
cache-downloads: true
- name: Update environment.fixed.yaml
run: |
mamba env export --file envs/environment.fixed.yaml --no-builds
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: update-environment-fixed
title: Update fixed environment
body: Automatically generated PR to update environment.fixed.yaml
labels: automated

View File

@ -1,151 +0,0 @@
name,GDP_PPP,country
3140,632728.0438507323,MD
3139,806541.9318093687,MD
3142,1392454.6690911907,MD
3152,897871.2903553953,MD
3246,645554.8588933202,MD
7049,1150156.4449477682,MD
1924,162285.16792916053,UA
1970,751970.6071848695,UA
2974,368873.75840156944,UA
2977,294847.85539198935,UA
2979,197988.13680768458,UA
2980,301371.2491126519,UA
3031,56925.21878805953,UA
3032,139395.18279351242,UA
3033,145377.8061037629,UA
3035,52282.83655208812,UA
3036,497950.25890516065,UA
3037,1183293.1987702171,UA
3038,255005.98207636533,UA
3039,224711.50098325178,UA
3040,342959.943226467,UA
3044,69119.31486955672,UA
3045,246273.65986119965,UA
3047,146742.08407299497,UA
3049,107265.7028733467,UA
3050,1126147.985259493,UA
3051,69833.56303043803,UA
3052,67230.88206577855,UA
3053,27019.224685201345,UA
3054,260571.47337292184,UA
3055,88760.94152915622,UA
3056,101368.26196568517,UA
3058,55752.92329667119,UA
3059,89024.37880630122,UA
3062,358411.291265149,UA
3064,75081.64142862396,UA
3065,158101.42949135564,UA
3066,83763.89576442329,UA
3068,173474.51218344545,UA
3069,60327.01572375589,UA
3070,18073.687271955278,UA
3071,249069.43314695224,UA
3072,220707.35700825177,UA
3073,61342.30137462664,UA
3074,254235.98867635374,UA
3077,769558.9832370486,UA
3078,132674.2315809836,UA
3079,1388517.1478032232,UA
3080,1861003.8718246964,UA
3082,140123.73854745473,UA
3083,834887.5595419679,UA
3084,1910795.5590558557,UA
3086,93828.36549170096,UA
3088,347197.65113392205,UA
3089,3754718.141734592,UA
3090,521912.69768585655,UA
3093,232818.05269714879,UA
3095,435376.20361377904,UA
3099,345596.5288937008,UA
3100,175689.10947424968,UA
3105,538438.9311459162,UA
3107,88096.86032871014,UA
3108,79847.68447063807,UA
3109,348504.73449373,UA
3144,71657.0165675802,UA
3146,80342.05037424155,UA
3158,74465.12922576343,UA
3164,3102112.2672631275,UA
3165,65215.04081671433,UA
3166,413924.2225725632,UA
3167,135060.0056434935,UA
3168,54980.442979330146,UA
3170,29584.879122227037,UA
3171,142780.68163047134,UA
3172,40436.63814695243,UA
3173,1253342.1790126422,UA
3174,173842.03139155387,UA
3176,65699.76352408895,UA
3177,143591.75419817626,UA
3178,56434.04525832523,UA
3179,389996.1670051216,UA
3180,138452.84503524794,UA
3181,67402.59500436619,UA
3184,51204.293695376415,UA
3185,46867.82356528432,UA
3186,103892.35612417295,UA
3187,193668.91476930346,UA
3189,54584.176457692694,UA
3190,219077.64942830536,UA
3197,88516.52699983507,UA
3198,298166.8272673622,UA
3199,61334.952541812374,UA
3229,175692.61136747137,UA
3230,106722.62773321665,UA
3236,61542.06264321315,UA
3241,83752.90489164277,UA
4301,48419.52825967164,UA
4305,147759.74280349456,UA
4306,53156.905740992224,UA
4315,218025.78516351627,UA
4317,155240.40554731718,UA
4318,1342144.2459407183,UA
4319,91669.1449633853,UA
4321,85852.49282415409,UA
4347,67938.7698430624,UA
4357,20064.979012172935,UA
4360,47840.51245168512,UA
4361,55580.924388032574,UA
4362,165753.82588729708,UA
4363,46390.2448142152,UA
4365,96265.47592938849,UA
4366,272003.25510057947,UA
4367,80878.50229245829,UA
4370,330072.35444044066,UA
4371,7707066.181975477,UA
4373,2019766.7891575783,UA
4374,985354.331818515,UA
4377,230805.08833664874,UA
4382,125670.67125287943,UA
4383,46914.065511740075,UA
4384,48020.804310510954,UA
4385,55612.34707641123,UA
4387,74558.3475791577,UA
4388,245243.33449409154,UA
4389,95696.56767732685,UA
4391,251085.7523045193,UA
4401,66375.82996856027,UA
4403,111954.41038437477,UA
4405,46911.68560148837,UA
4408,150782.51691456966,UA
4409,112776.7399582134,UA
4410,153076.56860965435,UA
4412,192629.31238456024,UA
4413,181295.3120834606,UA
4414,995694.9413199169,UA
4416,157640.7868989174,UA
4418,77580.20674809469,UA
4420,122320.99275223716,UA
4424,184891.10924920067,UA
4425,84486.75974340564,UA
4431,50485.84380961137,UA
4435,231040.45446464577,UA
4436,81222.18707585508,UA
4438,114819.76472988473,UA
4439,76839.1052178896,UA
4440,135337.0313562152,UA
4441,49159.485269198034,UA
7031,42001.73757065917,UA
7059,159790.48382874,UA
7063,39599.10564971086,UA
1 name GDP_PPP country
2 3140 632728.0438507323 MD
3 3139 806541.9318093687 MD
4 3142 1392454.6690911907 MD
5 3152 897871.2903553953 MD
6 3246 645554.8588933202 MD
7 7049 1150156.4449477682 MD
8 1924 162285.16792916053 UA
9 1970 751970.6071848695 UA
10 2974 368873.75840156944 UA
11 2977 294847.85539198935 UA
12 2979 197988.13680768458 UA
13 2980 301371.2491126519 UA
14 3031 56925.21878805953 UA
15 3032 139395.18279351242 UA
16 3033 145377.8061037629 UA
17 3035 52282.83655208812 UA
18 3036 497950.25890516065 UA
19 3037 1183293.1987702171 UA
20 3038 255005.98207636533 UA
21 3039 224711.50098325178 UA
22 3040 342959.943226467 UA
23 3044 69119.31486955672 UA
24 3045 246273.65986119965 UA
25 3047 146742.08407299497 UA
26 3049 107265.7028733467 UA
27 3050 1126147.985259493 UA
28 3051 69833.56303043803 UA
29 3052 67230.88206577855 UA
30 3053 27019.224685201345 UA
31 3054 260571.47337292184 UA
32 3055 88760.94152915622 UA
33 3056 101368.26196568517 UA
34 3058 55752.92329667119 UA
35 3059 89024.37880630122 UA
36 3062 358411.291265149 UA
37 3064 75081.64142862396 UA
38 3065 158101.42949135564 UA
39 3066 83763.89576442329 UA
40 3068 173474.51218344545 UA
41 3069 60327.01572375589 UA
42 3070 18073.687271955278 UA
43 3071 249069.43314695224 UA
44 3072 220707.35700825177 UA
45 3073 61342.30137462664 UA
46 3074 254235.98867635374 UA
47 3077 769558.9832370486 UA
48 3078 132674.2315809836 UA
49 3079 1388517.1478032232 UA
50 3080 1861003.8718246964 UA
51 3082 140123.73854745473 UA
52 3083 834887.5595419679 UA
53 3084 1910795.5590558557 UA
54 3086 93828.36549170096 UA
55 3088 347197.65113392205 UA
56 3089 3754718.141734592 UA
57 3090 521912.69768585655 UA
58 3093 232818.05269714879 UA
59 3095 435376.20361377904 UA
60 3099 345596.5288937008 UA
61 3100 175689.10947424968 UA
62 3105 538438.9311459162 UA
63 3107 88096.86032871014 UA
64 3108 79847.68447063807 UA
65 3109 348504.73449373 UA
66 3144 71657.0165675802 UA
67 3146 80342.05037424155 UA
68 3158 74465.12922576343 UA
69 3164 3102112.2672631275 UA
70 3165 65215.04081671433 UA
71 3166 413924.2225725632 UA
72 3167 135060.0056434935 UA
73 3168 54980.442979330146 UA
74 3170 29584.879122227037 UA
75 3171 142780.68163047134 UA
76 3172 40436.63814695243 UA
77 3173 1253342.1790126422 UA
78 3174 173842.03139155387 UA
79 3176 65699.76352408895 UA
80 3177 143591.75419817626 UA
81 3178 56434.04525832523 UA
82 3179 389996.1670051216 UA
83 3180 138452.84503524794 UA
84 3181 67402.59500436619 UA
85 3184 51204.293695376415 UA
86 3185 46867.82356528432 UA
87 3186 103892.35612417295 UA
88 3187 193668.91476930346 UA
89 3189 54584.176457692694 UA
90 3190 219077.64942830536 UA
91 3197 88516.52699983507 UA
92 3198 298166.8272673622 UA
93 3199 61334.952541812374 UA
94 3229 175692.61136747137 UA
95 3230 106722.62773321665 UA
96 3236 61542.06264321315 UA
97 3241 83752.90489164277 UA
98 4301 48419.52825967164 UA
99 4305 147759.74280349456 UA
100 4306 53156.905740992224 UA
101 4315 218025.78516351627 UA
102 4317 155240.40554731718 UA
103 4318 1342144.2459407183 UA
104 4319 91669.1449633853 UA
105 4321 85852.49282415409 UA
106 4347 67938.7698430624 UA
107 4357 20064.979012172935 UA
108 4360 47840.51245168512 UA
109 4361 55580.924388032574 UA
110 4362 165753.82588729708 UA
111 4363 46390.2448142152 UA
112 4365 96265.47592938849 UA
113 4366 272003.25510057947 UA
114 4367 80878.50229245829 UA
115 4370 330072.35444044066 UA
116 4371 7707066.181975477 UA
117 4373 2019766.7891575783 UA
118 4374 985354.331818515 UA
119 4377 230805.08833664874 UA
120 4382 125670.67125287943 UA
121 4383 46914.065511740075 UA
122 4384 48020.804310510954 UA
123 4385 55612.34707641123 UA
124 4387 74558.3475791577 UA
125 4388 245243.33449409154 UA
126 4389 95696.56767732685 UA
127 4391 251085.7523045193 UA
128 4401 66375.82996856027 UA
129 4403 111954.41038437477 UA
130 4405 46911.68560148837 UA
131 4408 150782.51691456966 UA
132 4409 112776.7399582134 UA
133 4410 153076.56860965435 UA
134 4412 192629.31238456024 UA
135 4413 181295.3120834606 UA
136 4414 995694.9413199169 UA
137 4416 157640.7868989174 UA
138 4418 77580.20674809469 UA
139 4420 122320.99275223716 UA
140 4424 184891.10924920067 UA
141 4425 84486.75974340564 UA
142 4431 50485.84380961137 UA
143 4435 231040.45446464577 UA
144 4436 81222.18707585508 UA
145 4438 114819.76472988473 UA
146 4439 76839.1052178896 UA
147 4440 135337.0313562152 UA
148 4441 49159.485269198034 UA
149 7031 42001.73757065917 UA
150 7059 159790.48382874 UA
151 7063 39599.10564971086 UA

View File

@ -5,7 +5,7 @@ biomass,--,"{true, false}",Flag to include biomass sector.
industry,--,"{true, false}",Flag to include industry sector.
agriculture,--,"{true, false}",Flag to include agriculture sector.
district_heating,--,,`prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_
-- potential,--,float,maximum fraction of urban demand which can be supplied by district heating
-- potential,--,float,maximum fraction of urban demand which can be supplied by district heating. Ignored where below current fraction.
-- progress,--,Dictionary with planning horizons as keys., Increase of today's district heating demand to potential maximum district heating share. Progress = 0 means today's district heating share. Progress = 1 means maximum fraction of urban demand is supplied by district heating
-- district_heating_loss,--,float,Share increase in district heat demand in urban central due to heat losses
cluster_heat_buses,--,"{true, false}",Cluster residential and service heat buses in `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_ to one to save memory.

1 Unit Values Description
5 industry -- {true, false} Flag to include industry sector.
6 agriculture -- {true, false} Flag to include agriculture sector.
7 district_heating -- `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_
8 -- potential -- float maximum fraction of urban demand which can be supplied by district heating maximum fraction of urban demand which can be supplied by district heating. Ignored where below current fraction.
9 -- progress -- Dictionary with planning horizons as keys. Increase of today's district heating demand to potential maximum district heating share. Progress = 0 means today's district heating share. Progress = 1 means maximum fraction of urban demand is supplied by district heating
10 -- district_heating_loss -- float Share increase in district heat demand in urban central due to heat losses
11 cluster_heat_buses -- {true, false} Cluster residential and service heat buses in `prepare_sector_network.py <https://github.com/PyPSA/pypsa-eur-sec/blob/master/scripts/prepare_sector_network.py>`_ to one to save memory.

View File

@ -31,6 +31,16 @@ Upcoming Release
* Bugfix: Correctly read in threshold capacity below which to remove components from previous planning horizons in :mod:`add_brownfield`.
* For countries not contained in the NUTS3-specific datasets (i.e. MD and UA), the mapping of GDP per capita and population per bus region used to spatially distribute electricity demand is now endogenised in a new rule :mod:`build_gdp_ppp_non_nuts3`. https://github.com/PyPSA/pypsa-eur/pull/1146
* The databundle has been updated to release v0.3.0, which includes raw GDP and population data for countries outside the NUTS system (UA, MD). https://github.com/PyPSA/pypsa-eur/pull/1146
* Updated filtering in :mod:`determine_availability_matrix_MD_UA.py` to improve speed. https://github.com/PyPSA/pypsa-eur/pull/1146
* Bugfix: Impose minimum value of zero for district heating progress between current and future market share in :mod:`build_district_heat_share`.
* Enable parallelism in :mod:`determine_availability_matrix_MD_UA.py` and remove plots. This requires the use of temporary files.
PyPSA-Eur 0.11.0 (25th May 2024)
=====================================

View File

@ -202,7 +202,6 @@ rule determine_availability_matrix_MD_UA:
+ ".nc",
output:
availability_matrix=resources("availability_matrix_MD-UA_{technology}.nc"),
availability_map=resources("availability_matrix_MD-UA_{technology}.png"),
log:
logs("determine_availability_matrix_MD_UA_{technology}.log"),
threads: config["atlite"].get("nprocesses", 4)
@ -375,6 +374,37 @@ def input_conventional(w):
}
# Optional input when having Ukraine (UA) or Moldova (MD) in the countries list
def input_gdp_pop_non_nuts3(w):
countries = set(config_provider("countries")(w))
if {"UA", "MD"}.intersection(countries):
return {"gdp_pop_non_nuts3": resources("gdp_pop_non_nuts3.geojson")}
return {}
rule build_gdp_pop_non_nuts3:
params:
countries=config_provider("countries"),
input:
base_network=resources("networks/base.nc"),
regions=resources("regions_onshore.geojson"),
gdp_non_nuts3="data/bundle/GDP_per_capita_PPP_1990_2015_v2.nc",
pop_non_nuts3="data/bundle/ppp_2013_1km_Aggregated.tif",
output:
resources("gdp_pop_non_nuts3.geojson"),
log:
logs("build_gdp_pop_non_nuts3.log"),
benchmark:
benchmarks("build_gdp_pop_non_nuts3")
threads: 1
resources:
mem_mb=8000,
conda:
"../envs/environment.yaml"
script:
"../scripts/build_gdp_pop_non_nuts3.py"
rule add_electricity:
params:
length_factor=config_provider("lines", "length_factor"),
@ -390,6 +420,7 @@ rule add_electricity:
input:
unpack(input_profile_tech),
unpack(input_conventional),
unpack(input_gdp_pop_non_nuts3),
base_network=resources("networks/base.nc"),
line_rating=lambda w: (
resources("networks/line_rating.nc")
@ -411,7 +442,6 @@ rule add_electricity:
),
load=resources("electricity_demand.csv"),
nuts3_shapes=resources("nuts3_shapes.geojson"),
ua_md_gdp="data/GDP_PPP_30arcsec_v3_mapped_default.csv",
output:
resources("networks/elec.nc"),
log:

View File

@ -55,7 +55,7 @@ def dynamic_getter(wildcards, keys, default):
scenario_name = wildcards.run
if scenario_name not in scenarios:
raise ValueError(
f"Scenario {scenario_name} not found in file {config['run']['scenario']['file']}."
f"Scenario {scenario_name} not found in file {config['run']['scenarios']['file']}."
)
config_with_scenario = scenario_config(scenario_name)
config_with_wildcards = update_config_from_wildcards(
@ -81,7 +81,8 @@ def config_provider(*keys, default=None):
def solver_threads(w):
solver_options = config_provider("solving", "solver_options")(w)
option_set = config_provider("solving", "solver", "options")(w)
threads = solver_options[option_set].get("threads", 4)
solver_option_set = solver_options[option_set]
threads = solver_option_set.get("threads") or solver_option_set.get("Threads") or 4
return threads

View File

@ -29,6 +29,8 @@ if config["enable"]["retrieve"] and config["enable"].get("retrieve_databundle",
"h2_salt_caverns_GWh_per_sqkm.geojson",
"natura/natura.tiff",
"gebco/GEBCO_2014_2D.nc",
"GDP_per_capita_PPP_1990_2015_v2.nc",
"ppp_2013_1km_Aggregated.tif",
]
rule retrieve_databundle:
@ -172,7 +174,7 @@ if config["enable"]["retrieve"]:
rule retrieve_ship_raster:
input:
storage(
"https://zenodo.org/records/10973944/files/shipdensity_global.zip",
"https://zenodo.org/records/12760663/files/shipdensity_global.zip",
keep_local=True,
),
output:

View File

@ -294,19 +294,19 @@ def shapes_to_shapes(orig, dest):
return transfer
def attach_load(n, regions, load, nuts3_shapes, ua_md_gdp, countries, scaling=1.0):
def attach_load(
n, regions, load, nuts3_shapes, gdp_pop_non_nuts3, countries, scaling=1.0
):
substation_lv_i = n.buses.index[n.buses["substation_lv"]]
regions = gpd.read_file(regions).set_index("name").reindex(substation_lv_i)
gdf_regions = gpd.read_file(regions).set_index("name").reindex(substation_lv_i)
opsd_load = pd.read_csv(load, index_col=0, parse_dates=True).filter(items=countries)
ua_md_gdp = pd.read_csv(ua_md_gdp, dtype={"name": "str"}).set_index("name")
logger.info(f"Load data scaled by factor {scaling}.")
opsd_load *= scaling
nuts3 = gpd.read_file(nuts3_shapes).set_index("index")
def upsample(cntry, group):
def upsample(cntry, group, gdp_pop_non_nuts3):
load = opsd_load[cntry]
if len(group) == 1:
@ -325,7 +325,15 @@ def attach_load(n, regions, load, nuts3_shapes, ua_md_gdp, countries, scaling=1.
factors = normed(0.6 * normed(gdp_n) + 0.4 * normed(pop_n))
if cntry in ["UA", "MD"]:
# overwrite factor because nuts3 provides no data for UA+MD
factors = normed(ua_md_gdp.loc[group.index, "GDP_PPP"].squeeze())
gdp_pop_non_nuts3 = gpd.read_file(gdp_pop_non_nuts3).set_index("Bus")
gdp_pop_non_nuts3 = gdp_pop_non_nuts3.loc[
(gdp_pop_non_nuts3.country == cntry)
& (gdp_pop_non_nuts3.index.isin(substation_lv_i))
]
factors = normed(
0.6 * normed(gdp_pop_non_nuts3["gdp"])
+ 0.4 * normed(gdp_pop_non_nuts3["pop"])
)
return pd.DataFrame(
factors.values * load.values[:, np.newaxis],
index=load.index,
@ -334,8 +342,8 @@ def attach_load(n, regions, load, nuts3_shapes, ua_md_gdp, countries, scaling=1.
load = pd.concat(
[
upsample(cntry, group)
for cntry, group in regions.geometry.groupby(regions.country)
upsample(cntry, group, gdp_pop_non_nuts3)
for cntry, group in gdf_regions.geometry.groupby(gdf_regions.country)
],
axis=1,
)
@ -821,7 +829,7 @@ if __name__ == "__main__":
snakemake.input.regions,
snakemake.input.load,
snakemake.input.nuts3_shapes,
snakemake.input.ua_md_gdp,
snakemake.input.get("gdp_pop_non_nuts3"),
params.countries,
params.scaling_factor,
)

View File

@ -86,7 +86,7 @@ if __name__ == "__main__":
urban_fraction = pd.concat([urban_fraction, dist_fraction_node], axis=1).max(axis=1)
# difference of max potential and today's share of district heating
diff = (urban_fraction * central_fraction) - dist_fraction_node
diff = ((urban_fraction * central_fraction) - dist_fraction_node).clip(lower=0)
progress = get(
snakemake.config["sector"]["district_heating"]["progress"], investment_year
)

View File

@ -0,0 +1,153 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
"""
Maps the per-capita GDP and population values to non-NUTS3 regions.
The script takes as input the country code, a GeoDataFrame containing
the regions, and the file paths to the datasets containing the GDP and
POP values for non-NUTS3 countries.
"""
import logging
import geopandas as gpd
import numpy as np
import pandas as pd
import pypsa
import rasterio
import xarray as xr
from _helpers import configure_logging, set_scenario_config
from rasterio.mask import mask
from shapely.geometry import box
logger = logging.getLogger(__name__)
def calc_gdp_pop(country, regions, gdp_non_nuts3, pop_non_nuts3):
"""
Calculate the GDP p.c. and population values for non NUTS3 regions.
Parameters:
country (str): The two-letter country code of the non-NUTS3 region.
regions (GeoDataFrame): A GeoDataFrame containing the regions.
gdp_non_nuts3 (str): The file path to the dataset containing the GDP p.c values
for non NUTS3 countries (e.g. MD, UA)
pop_non_nuts3 (str): The file path to the dataset containing the POP values
for non NUTS3 countries (e.g. MD, UA)
Returns:
tuple: A tuple containing two GeoDataFrames:
- gdp: A GeoDataFrame with the mean GDP p.c. values mapped to each bus.
- pop: A GeoDataFrame with the summed POP values mapped to each bus.
"""
regions = (
regions.rename(columns={"name": "Bus"})
.drop(columns=["x", "y"])
.set_index("Bus")
)
regions = regions[regions.country == country]
# Create a bounding box for UA, MD from region shape, including a buffer of 10000 metres
bounding_box = (
gpd.GeoDataFrame(geometry=[box(*regions.total_bounds)], crs=regions.crs)
.to_crs(epsg=3857)
.buffer(10000)
.to_crs(regions.crs)
)
# GDP Mapping
logger.info(f"Mapping mean GDP p.c. to non-NUTS3 region: {country}")
with xr.open_dataset(gdp_non_nuts3) as src_gdp:
src_gdp = src_gdp.where(
(src_gdp.longitude >= bounding_box.bounds.minx.min())
& (src_gdp.longitude <= bounding_box.bounds.maxx.max())
& (src_gdp.latitude >= bounding_box.bounds.miny.min())
& (src_gdp.latitude <= bounding_box.bounds.maxy.max()),
drop=True,
)
gdp = src_gdp.to_dataframe().reset_index()
gdp = gdp.rename(columns={"GDP_per_capita_PPP": "gdp"})
gdp = gdp[gdp.time == gdp.time.max()]
gdp_raster = gpd.GeoDataFrame(
gdp,
geometry=gpd.points_from_xy(gdp.longitude, gdp.latitude),
crs="EPSG:4326",
)
gdp_mapped = gpd.sjoin(gdp_raster, regions, predicate="within")
gdp = (
gdp_mapped.copy()
.groupby(["Bus", "country"])
.agg({"gdp": "mean"})
.reset_index(level=["country"])
)
# Population Mapping
logger.info(f"Mapping summed population to non-NUTS3 region: {country}")
with rasterio.open(pop_non_nuts3) as src_pop:
# Mask the raster with the bounding box
out_image, out_transform = mask(src_pop, bounding_box, crop=True)
out_meta = src_pop.meta.copy()
out_meta.update(
{
"driver": "GTiff",
"height": out_image.shape[1],
"width": out_image.shape[2],
"transform": out_transform,
}
)
masked_data = out_image[0] # Use the first band (rest is empty)
row_indices, col_indices = np.where(masked_data != src_pop.nodata)
values = masked_data[row_indices, col_indices]
# Affine transformation from pixel coordinates to geo coordinates
x_coords, y_coords = rasterio.transform.xy(out_transform, row_indices, col_indices)
pop_raster = pd.DataFrame({"x": x_coords, "y": y_coords, "pop": values})
pop_raster = gpd.GeoDataFrame(
pop_raster,
geometry=gpd.points_from_xy(pop_raster.x, pop_raster.y),
crs=src_pop.crs,
)
pop_mapped = gpd.sjoin(pop_raster, regions, predicate="within")
pop = (
pop_mapped.groupby(["Bus", "country"])
.agg({"pop": "sum"})
.reset_index()
.set_index("Bus")
)
gdp_pop = regions.join(gdp.drop(columns="country"), on="Bus").join(
pop.drop(columns="country"), on="Bus"
)
gdp_pop.fillna(0, inplace=True)
return gdp_pop
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
snakemake = mock_snakemake("build_gdp_pop_non_nuts3")
configure_logging(snakemake)
set_scenario_config(snakemake)
n = pypsa.Network(snakemake.input.base_network)
regions = gpd.read_file(snakemake.input.regions)
gdp_non_nuts3 = snakemake.input.gdp_non_nuts3
pop_non_nuts3 = snakemake.input.pop_non_nuts3
subset = {"MD", "UA"}.intersection(snakemake.params.countries)
gdp_pop = pd.concat(
[
calc_gdp_pop(country, regions, gdp_non_nuts3, pop_non_nuts3)
for country in subset
],
axis=0,
)
logger.info(
f"Exporting GDP and POP values for non-NUTS3 regions {snakemake.output}"
)
gdp_pop.reset_index().to_file(snakemake.output, driver="GeoJSON")

View File

@ -8,16 +8,15 @@ Create land elibility analysis for Ukraine and Moldova with different datasets.
import functools
import logging
import os
import time
from tempfile import NamedTemporaryFile
import atlite
import fiona
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np
from _helpers import configure_logging, set_scenario_config
from atlite.gis import shape_availability
from rasterio.plot import show
logger = logging.getLogger(__name__)
@ -40,7 +39,7 @@ if __name__ == "__main__":
configure_logging(snakemake)
set_scenario_config(snakemake)
nprocesses = None # snakemake.config["atlite"].get("nprocesses")
nprocesses = int(snakemake.threads)
noprogress = not snakemake.config["atlite"].get("show_progress", True)
config = snakemake.config["renewable"][snakemake.wildcards.technology]
@ -48,7 +47,9 @@ if __name__ == "__main__":
regions = (
gpd.read_file(snakemake.input.regions).set_index("name").rename_axis("bus")
)
buses = regions.index
# Limit to "UA" and "MD" regions
buses = regions.loc[regions["country"].isin(["UA", "MD"])].index.values
regions = regions.loc[buses]
excluder = atlite.ExclusionContainer(crs=3035, res=100)
@ -93,8 +94,15 @@ if __name__ == "__main__":
bbox=regions.geometry,
layer=layer,
).to_crs(3035)
# temporary file needed for parallelization
with NamedTemporaryFile(suffix=".geojson", delete=False) as f:
plg_tmp_fn = f.name
if not wdpa.empty:
excluder.add_geometry(wdpa.geometry)
wdpa[["geometry"]].to_file(plg_tmp_fn)
while not os.path.exists(plg_tmp_fn):
time.sleep(1)
excluder.add_geometry(plg_tmp_fn)
layer = get_wdpa_layer_name(wdpa_fn, "points")
wdpa_pts = gpd.read_file(
@ -107,8 +115,15 @@ if __name__ == "__main__":
wdpa_pts = wdpa_pts.set_geometry(
wdpa_pts["geometry"].buffer(wdpa_pts["buffer_radius"])
)
# temporary file needed for parallelization
with NamedTemporaryFile(suffix=".geojson", delete=False) as f:
pts_tmp_fn = f.name
if not wdpa_pts.empty:
excluder.add_geometry(wdpa_pts.geometry)
wdpa_pts[["geometry"]].to_file(pts_tmp_fn)
while not os.path.exists(pts_tmp_fn):
time.sleep(1)
excluder.add_geometry(pts_tmp_fn)
if "max_depth" in config:
# lambda not supported for atlite + multiprocessing
@ -144,16 +159,10 @@ if __name__ == "__main__":
else:
availability = cutout.availabilitymatrix(regions, excluder, **kwargs)
regions_geometry = regions.to_crs(3035).geometry
band, transform = shape_availability(regions_geometry, excluder)
fig, ax = plt.subplots(figsize=(4, 8))
gpd.GeoSeries(regions_geometry.union_all()).plot(ax=ax, color="none")
show(band, transform=transform, cmap="Greens", ax=ax)
plt.axis("off")
plt.savefig(snakemake.output.availability_map, bbox_inches="tight", dpi=500)
for fn in [pts_tmp_fn, plg_tmp_fn]:
if os.path.exists(fn):
os.remove(fn)
# Limit results only to buses for UA and MD
buses = regions.loc[regions["country"].isin(["UA", "MD"])].index.values
availability = availability.sel(bus=buses)
# Save and plot for verification

View File

@ -688,7 +688,7 @@ def add_co2_tracking(n, costs, options):
e_nom_extendable=True,
e_nom_max=e_nom_max,
capital_cost=options["co2_sequestration_cost"],
marginal_cost=0.1,
marginal_cost=-0.1,
bus=sequestration_buses,
lifetime=options["co2_sequestration_lifetime"],
carrier="co2 sequestered",

View File

@ -48,7 +48,7 @@ if __name__ == "__main__":
configure_logging(snakemake)
set_scenario_config(snakemake)
url = "https://zenodo.org/records/10973944/files/bundle.tar.xz"
url = "https://zenodo.org/records/12760663/files/bundle.tar.xz"
tarball_fn = Path(f"{rootpath}/bundle.tar.xz")
to_fn = Path(rootpath) / Path(snakemake.output[0]).parent.parent