Merge branch 'master' into jrc-idees-2020
This commit is contained in:
commit
8f2cea4d93
39
.github/workflows/update-fixed-env.yaml
vendored
Normal file
39
.github/workflows/update-fixed-env.yaml
vendored
Normal 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
|
@ -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
|
|
@ -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.
|
||||
|
|
@ -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)
|
||||
=====================================
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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
|
||||
)
|
||||
|
153
scripts/build_gdp_pop_non_nuts3.py
Normal file
153
scripts/build_gdp_pop_non_nuts3.py
Normal 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")
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user