Revert "remove build/retrieve natura raster, directly use shapefile"

This commit is contained in:
Fabian Neumann 2022-06-27 19:00:41 +02:00 committed by GitHub
parent d3afd21377
commit 51de606aab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 200 additions and 40 deletions

View File

@ -13,12 +13,13 @@ on:
branches: branches:
- master - master
pull_request: pull_request:
branches:
- master
schedule: schedule:
- cron: "0 5 * * TUE" - cron: "0 5 * * TUE"
env: env:
CONDA_CACHE_NUMBER: 1 # Change this value to manually reset the environment cache CACHE_NUMBER: 1 # Change this value to manually reset the environment cache
DATA_CACHE_NUMBER: 1
jobs: jobs:
build: build:
@ -65,26 +66,16 @@ jobs:
miniforge-version: latest miniforge-version: latest
activate-environment: pypsa-eur activate-environment: pypsa-eur
use-mamba: true use-mamba: true
- name: Set cache dates - name: Set cache date
run: | run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV
echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV
echo "WEEK=$(date +'%Y%U')" >> $GITHUB_ENV
- name: Cache data and cutouts folders
uses: actions/cache@v3
with:
path: |
data
cutouts
key: data-cutouts-${{ env.WEEK }}-${{ env.DATA_CACHE_NUMBER }}
- name: Create environment cache - name: Create environment cache
uses: actions/cache@v2 uses: actions/cache@v2
id: cache id: cache
with: with:
path: ${{ matrix.prefix }} path: ${{ matrix.prefix }}
key: ${{ matrix.label }}-conda-${{ hashFiles('envs/environment.yaml') }}-${{ env.DATE }}-${{ env.CONDA_CACHE_NUMBER }} key: ${{ matrix.label }}-conda-${{ hashFiles('envs/environment.yaml') }}-${{ env.DATE }}-${{ env.CACHE_NUMBER }}
- name: Update environment due to outdated or unavailable cache - name: Update environment due to outdated or unavailable cache
run: mamba env update -n pypsa-eur -f envs/environment.yaml run: mamba env update -n pypsa-eur -f envs/environment.yaml

View File

@ -67,12 +67,6 @@ if config['enable'].get('retrieve_databundle', True):
script: 'scripts/retrieve_databundle.py' script: 'scripts/retrieve_databundle.py'
rule retrieve_natura_data:
input: HTTP.remote("sdi.eea.europa.eu/datashare/s/H6QGCybMdLLnywo/download", additional_request_string="?path=%2FNatura2000_end2020_gpkg&files=Natura2000_end2020.gpkg", static=True)
output: "data/Natura2000_end2020.gpkg"
run: move(input[0], output[0])
rule retrieve_load_data: rule retrieve_load_data:
input: HTTP.remote("data.open-power-system-data.org/time_series/2019-06-05/time_series_60min_singleindex.csv", keep_local=True, static=True) input: HTTP.remote("data.open-power-system-data.org/time_series/2019-06-05/time_series_60min_singleindex.csv", keep_local=True, static=True)
output: "data/load_raw.csv" output: "data/load_raw.csv"
@ -171,13 +165,28 @@ if config['enable'].get('retrieve_cutout', True):
run: move(input[0], output[0]) run: move(input[0], output[0])
if config['enable'].get('build_natura_raster', False):
rule build_natura_raster:
input:
natura="data/bundle/natura/Natura2000_end2015.shp",
cutouts=expand("cutouts/{cutouts}.nc", **config['atlite'])
output: "resources/natura.tiff"
log: "logs/build_natura_raster.log"
script: "scripts/build_natura_raster.py"
if config['enable'].get('retrieve_natura_raster', True):
rule retrieve_natura_raster:
input: HTTP.remote("zenodo.org/record/4706686/files/natura.tiff", keep_local=True, static=True)
output: "resources/natura.tiff"
run: move(input[0], output[0])
rule build_renewable_profiles: rule build_renewable_profiles:
input: input:
base_network="networks/base.nc", base_network="networks/base.nc",
corine="data/bundle/corine/g250_clc06_V18_5.tif", corine="data/bundle/corine/g250_clc06_V18_5.tif",
natura=lambda w: ("data/Natura2000_end2020.gpkg" natura="resources/natura.tiff",
if config["renewable"][w.technology]["natura"]
else []),
gebco=lambda w: ("data/bundle/GEBCO_2014_2D.nc" gebco=lambda w: ("data/bundle/GEBCO_2014_2D.nc"
if "max_depth" in config["renewable"][w.technology].keys() if "max_depth" in config["renewable"][w.technology].keys()
else []), else []),

View File

@ -43,6 +43,8 @@ enable:
retrieve_databundle: true retrieve_databundle: true
build_cutout: false build_cutout: false
retrieve_cutout: true retrieve_cutout: true
build_natura_raster: false
retrieve_natura_raster: true
custom_busmap: false custom_busmap: false
electricity: electricity:

View File

@ -43,6 +43,8 @@ enable:
retrieve_databundle: true retrieve_databundle: true
build_cutout: false build_cutout: false
retrieve_cutout: true retrieve_cutout: true
build_natura_raster: false
retrieve_natura_raster: true
custom_busmap: false custom_busmap: false
electricity: electricity:
@ -87,7 +89,7 @@ renewable:
24, 25, 26, 27, 28, 29, 31, 32] 24, 25, 26, 27, 28, 29, 31, 32]
distance: 1000 distance: 1000
distance_grid_codes: [1, 2, 3, 4, 5, 6] distance_grid_codes: [1, 2, 3, 4, 5, 6]
natura: false natura: true
potential: simple # or conservative potential: simple # or conservative
clip_p_max_pu: 1.e-2 clip_p_max_pu: 1.e-2
offwind-ac: offwind-ac:
@ -98,7 +100,7 @@ renewable:
capacity_per_sqkm: 3 capacity_per_sqkm: 3
# correction_factor: 0.93 # correction_factor: 0.93
corine: [44, 255] corine: [44, 255]
natura: false natura: true
max_shore_distance: 30000 max_shore_distance: 30000
potential: simple # or conservative potential: simple # or conservative
clip_p_max_pu: 1.e-2 clip_p_max_pu: 1.e-2
@ -111,7 +113,7 @@ renewable:
capacity_per_sqkm: 3 capacity_per_sqkm: 3
# correction_factor: 0.93 # correction_factor: 0.93
corine: [44, 255] corine: [44, 255]
natura: false natura: true
min_shore_distance: 30000 min_shore_distance: 30000
potential: simple # or conservative potential: simple # or conservative
clip_p_max_pu: 1.e-2 clip_p_max_pu: 1.e-2
@ -133,7 +135,7 @@ renewable:
# correction_factor: 0.854337 # correction_factor: 0.854337
corine: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, corine: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 26, 31, 32] 14, 15, 16, 17, 18, 19, 20, 26, 31, 32]
natura: false natura: true
potential: simple # or conservative potential: simple # or conservative
clip_p_max_pu: 1.e-2 clip_p_max_pu: 1.e-2

View File

@ -12,4 +12,6 @@ enable,,,
-- retrieve_databundle,bool,"{true, false}","Switch to retrieve databundle from zenodo via the rule :mod:`retrieve_databundle` or whether to keep a custom databundle located in the corresponding folder." -- retrieve_databundle,bool,"{true, false}","Switch to retrieve databundle from zenodo via the rule :mod:`retrieve_databundle` or whether to keep a custom databundle located in the corresponding folder."
-- build_cutout,bool,"{true, false}","Switch to enable the building of cutouts via the rule :mod:`build_cutout`." -- build_cutout,bool,"{true, false}","Switch to enable the building of cutouts via the rule :mod:`build_cutout`."
-- retrieve_cutout,bool,"{true, false}","Switch to enable the retrieval of cutouts from zenodo with :mod:`retrieve_cutout`." -- retrieve_cutout,bool,"{true, false}","Switch to enable the retrieval of cutouts from zenodo with :mod:`retrieve_cutout`."
-- build_natura_raster,bool,"{true, false}","Switch to enable the creation of the raster ``natura.tiff`` via the rule :mod:`build_natura_raster`."
-- retrieve_natura_raster,bool,"{true, false}","Switch to enable the retrieval of ``natura.tiff`` from zenodo with :mod:`retrieve_natura_raster`."
-- custom_busmap,bool,"{true, false}","Switch to enable the use of custom busmaps in rule :mod:`cluster_network`. If activated the rule looks for provided busmaps at ``data/custom_busmap_elec_s{simpl}_{clusters}.csv`` which should have the same format as ``resources/busmap_elec_s{simpl}_{clusters}.csv``, i.e. the index should contain the buses of ``networks/elec_s{simpl}.nc``." -- custom_busmap,bool,"{true, false}","Switch to enable the use of custom busmaps in rule :mod:`cluster_network`. If activated the rule looks for provided busmaps at ``data/custom_busmap_elec_s{simpl}_{clusters}.csv`` which should have the same format as ``resources/busmap_elec_s{simpl}_{clusters}.csv``, i.e. the index should contain the buses of ``networks/elec_s{simpl}.nc``."

1 Unit Values Description
12 -- retrieve_databundle bool {true, false} Switch to retrieve databundle from zenodo via the rule :mod:`retrieve_databundle` or whether to keep a custom databundle located in the corresponding folder.
13 -- build_cutout bool {true, false} Switch to enable the building of cutouts via the rule :mod:`build_cutout`.
14 -- retrieve_cutout bool {true, false} Switch to enable the retrieval of cutouts from zenodo with :mod:`retrieve_cutout`.
15 -- build_natura_raster bool {true, false} Switch to enable the creation of the raster ``natura.tiff`` via the rule :mod:`build_natura_raster`.
16 -- retrieve_natura_raster bool {true, false} Switch to enable the retrieval of ``natura.tiff`` from zenodo with :mod:`retrieve_natura_raster`.
17 -- custom_busmap bool {true, false} Switch to enable the use of custom busmaps in rule :mod:`cluster_network`. If activated the rule looks for provided busmaps at ``data/custom_busmap_elec_s{simpl}_{clusters}.csv`` which should have the same format as ``resources/busmap_elec_s{simpl}_{clusters}.csv``, i.e. the index should contain the buses of ``networks/elec_s{simpl}.nc``.

View File

@ -27,6 +27,7 @@ With these and the externally extracted ENTSO-E online map topology
Then the process continues by calculating conventional power plant capacities, potentials, and per-unit availability time series for variable renewable energy carriers and hydro power plants with the following rules: Then the process continues by calculating conventional power plant capacities, potentials, and per-unit availability time series for variable renewable energy carriers and hydro power plants with the following rules:
- :mod:`build_powerplants` for today's thermal power plant capacities using `powerplantmatching <https://github.com/FRESNA/powerplantmatching>`_ allocating these to the closest substation for each powerplant, - :mod:`build_powerplants` for today's thermal power plant capacities using `powerplantmatching <https://github.com/FRESNA/powerplantmatching>`_ allocating these to the closest substation for each powerplant,
- :mod:`build_natura_raster` for rasterising NATURA2000 natural protection areas,
- :mod:`build_renewable_profiles` for the hourly capacity factors and installation potentials constrained by land-use in each substation's Voronoi cell for PV, onshore and offshore wind, and - :mod:`build_renewable_profiles` for the hourly capacity factors and installation potentials constrained by land-use in each substation's Voronoi cell for PV, onshore and offshore wind, and
- :mod:`build_hydro_profile` for the hourly per-unit hydro power availability time series. - :mod:`build_hydro_profile` for the hourly per-unit hydro power availability time series.
@ -40,6 +41,7 @@ together into a detailed PyPSA network stored in ``networks/elec.nc``.
preparation/build_shapes preparation/build_shapes
preparation/build_load_data preparation/build_load_data
preparation/build_cutout preparation/build_cutout
preparation/build_natura_raster
preparation/prepare_links_p_nom preparation/prepare_links_p_nom
preparation/base_network preparation/base_network
preparation/build_bus_regions preparation/build_bus_regions

View File

@ -0,0 +1,39 @@
..
SPDX-FileCopyrightText: 2019-2020 The PyPSA-Eur Authors
SPDX-License-Identifier: CC-BY-4.0
.. _natura:
Rule ``build_natura_raster``
===============================
.. graphviz::
:align: center
digraph snakemake_dag {
graph [bgcolor=white,
margin=0,
size="8,5"
];
node [fontname=sans,
fontsize=10,
penwidth=2,
shape=box,
style=rounded
];
edge [color=grey,
penwidth=2
];
9 [color="0.22 0.6 0.85",
label=build_renewable_profiles];
12 [color="0.31 0.6 0.85",
fillcolor=gray,
label=build_natura_raster,
style=filled];
12 -> 9;
}
|
.. automodule:: build_natura_raster

View File

@ -41,6 +41,9 @@ Rule ``build_renewable_profiles``
8 [color="0.00 0.6 0.85", 8 [color="0.00 0.6 0.85",
label=build_shapes]; label=build_shapes];
8 -> 9; 8 -> 9;
12 [color="0.31 0.6 0.85",
label=build_natura_raster];
12 -> 9;
13 [color="0.56 0.6 0.85", 13 [color="0.56 0.6 0.85",
label=build_cutout]; label=build_cutout];
13 -> 9; 13 -> 9;

View File

@ -50,3 +50,30 @@ The :ref:`tutorial` uses a smaller cutout than required for the full model (30 M
.. seealso:: .. seealso::
For details see :mod:`build_cutout` and read the `atlite documentation <https://atlite.readthedocs.io>`_. For details see :mod:`build_cutout` and read the `atlite documentation <https://atlite.readthedocs.io>`_.
Rule ``retrieve_natura_raster``
-------------------------------
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.4706686.svg
:target: https://doi.org/10.5281/zenodo.4706686
This rule, as a substitute for :mod:`build_natura_raster`, downloads an already rasterized version (`natura.tiff <https://zenodo.org/record/4706686/files/natura.tiff>`_) of `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas to reduce computation times. The file is placed into the ``resources`` sub-directory.
**Relevant Settings**
.. code:: yaml
enable:
build_natura_raster:
.. seealso::
Documentation of the configuration file ``config.yaml`` at
:ref:`toplevel_cf`
**Outputs**
- ``resources/natura.tiff``: Rasterized version of `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas to reduce computation times.
.. seealso::
For details see :mod:`build_natura_raster`.

View File

@ -62,11 +62,6 @@ Upcoming Release
* New network topology extracted from the ENTSO-E interactive map. * New network topology extracted from the ENTSO-E interactive map.
* Remove rules to build or retrieve rasterized NATURA 2000 dataset. Renewable potential calculation now directly uses the shapefiles.
* Cache data and cutouts folders. This cache will be updated weekly.
* Add rule to automatically retrieve Natura2000 natural protection areas. Switch of file format to GPKG.
* The unused argument ``simple_hvdc_costs`` in :mod:`add_electricity` was removed. * The unused argument ``simple_hvdc_costs`` in :mod:`add_electricity` was removed.
* Iterative solving with impedance updates is skipped if there are no expandable lines. * Iterative solving with impedance updates is skipped if there are no expandable lines.

View File

@ -35,8 +35,8 @@ To run the tutorial, use this as your configuration file ``config.yaml``.
.../pypsa-eur % cp config.tutorial.yaml config.yaml .../pypsa-eur % cp config.tutorial.yaml config.yaml
This configuration is set to download a reduced data set via the rules :mod:`retrieve_databundle` This configuration is set to download a reduced data set via the rules :mod:`retrieve_databundle`,
and :mod:`retrieve_cutout` totalling at less than 250 MB. :mod:`retrieve_natura_raster`, :mod:`retrieve_cutout` totalling at less than 250 MB.
The full set of data dependencies would consume 5.3 GB. The full set of data dependencies would consume 5.3 GB.
For more information on the data dependencies of PyPSA-Eur, continue reading :ref:`data`. For more information on the data dependencies of PyPSA-Eur, continue reading :ref:`data`.

View File

@ -45,7 +45,6 @@ dependencies:
# GIS dependencies: # GIS dependencies:
- cartopy - cartopy
- descartes - descartes
- fiona # explicit for Windows
- rasterio<=1.2.9 # 1.2.10 creates error https://github.com/PyPSA/atlite/issues/238 - rasterio<=1.2.9 # 1.2.10 creates error https://github.com/PyPSA/atlite/issues/238
# PyPSA-Eur-Sec Dependencies # PyPSA-Eur-Sec Dependencies

View File

@ -0,0 +1,89 @@
# SPDX-FileCopyrightText: : 2017-2020 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
"""
Rasters the vector data of the `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas onto all cutout regions.
Relevant Settings
-----------------
.. code:: yaml
renewable:
{technology}:
cutout:
.. seealso::
Documentation of the configuration file ``config.yaml`` at
:ref:`renewable_cf`
Inputs
------
- ``data/bundle/natura/Natura2000_end2015.shp``: `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas.
.. image:: ../img/natura.png
:scale: 33 %
Outputs
-------
- ``resources/natura.tiff``: Rasterized version of `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas to reduce computation times.
.. image:: ../img/natura.png
:scale: 33 %
Description
-----------
"""
import logging
from _helpers import configure_logging
import atlite
import geopandas as gpd
import rasterio as rio
from rasterio.features import geometry_mask
from rasterio.warp import transform_bounds
logger = logging.getLogger(__name__)
def determine_cutout_xXyY(cutout_name):
cutout = atlite.Cutout(cutout_name)
assert cutout.crs.to_epsg() == 4326
x, X, y, Y = cutout.extent
dx, dy = cutout.dx, cutout.dy
return [x - dx/2., X + dx/2., y - dy/2., Y + dy/2.]
def get_transform_and_shape(bounds, res):
left, bottom = [(b // res)* res for b in bounds[:2]]
right, top = [(b // res + 1) * res for b in bounds[2:]]
shape = int((top - bottom) // res), int((right - left) / res)
transform = rio.Affine(res, 0, left, 0, -res, top)
return transform, shape
if __name__ == "__main__":
if 'snakemake' not in globals():
from _helpers import mock_snakemake
snakemake = mock_snakemake('build_natura_raster')
configure_logging(snakemake)
cutouts = snakemake.input.cutouts
xs, Xs, ys, Ys = zip(*(determine_cutout_xXyY(cutout) for cutout in cutouts))
bounds = transform_bounds(4326, 3035, min(xs), min(ys), max(Xs), max(Ys))
transform, out_shape = get_transform_and_shape(bounds, res=100)
# adjusted boundaries
shapes = gpd.read_file(snakemake.input.natura).to_crs(3035)
raster = ~geometry_mask(shapes.geometry, out_shape[::-1], transform)
raster = raster.astype(rio.uint8)
with rio.open(snakemake.output[0], 'w', driver='GTiff', dtype=rio.uint8,
count=1, transform=transform, crs=3035, compress='lzw',
width=raster.shape[1], height=raster.shape[0]) as dst:
dst.write(raster, indexes=1)

View File

@ -227,9 +227,7 @@ if __name__ == '__main__':
excluder = atlite.ExclusionContainer(crs=3035, res=100) excluder = atlite.ExclusionContainer(crs=3035, res=100)
if config['natura']: if config['natura']:
mask = regions.to_crs(3035).buffer(0) # buffer to avoid invalid geometry excluder.add_raster(snakemake.input.natura, nodata=0, allow_no_overlap=True)
natura = gpd.read_file(snakemake.input.natura, mask=mask)
excluder.add_geometry(natura.geometry)
corine = config.get("corine", {}) corine = config.get("corine", {})
if "grid_codes" in corine: if "grid_codes" in corine:

View File

@ -42,6 +42,8 @@ enable:
retrieve_databundle: true retrieve_databundle: true
build_cutout: false build_cutout: false
retrieve_cutout: true retrieve_cutout: true
build_natura_raster: false
retrieve_natura_raster: true
custom_busmap: false custom_busmap: false
electricity: electricity: