Skip to content

Commit

Permalink
Introducing OpenStreetMap high-voltage grid to PyPSA-Eur (#1079)
Browse files Browse the repository at this point in the history
* Implemented  which uses the overpass API to download power features for individual countries.

* Extended  rule by input.

* Bug fixes and improvements to clean_osm_data.py. Added  in retrieve_osm_data.py.

* Updated clean_osm_data and retrieve_osm_data to create clean substations.

* Finished clean_osm_data function.

* Added check whether line is a circle. If so, drop it.

* Extended build_electricity.smk by build_osm_network.py

* Added build_osm_network

* Working osm-network-fast

* Bug fixes.

* Finalised and cleaned  including docstrings.

* Added try catch to retrieve_osm_data. Allows for parallelisation of downloads.

* Updated cleaning process.

* Set maximum number of threads for retrieving to 4, wrt. fair usage policy and potential request errors.

* Intermediate update on clean_osm_data.py. Added docstrings.

* Bug fix.

* Bug fix.

* Bug fixes in data types out of clean_osm_data

* Significant improvements to retrieve_osm_data, clean_osm_data. Cleaned code. Speed improvements

* Cleaned config.

* Fixes.

* Bug fixes.

* Updated default config

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Removed overpass from required packages. Not needed anymore.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added links_relations (route = power, frequency = 0) to retrieval. This will change how HVDC links are extracted in the near future.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Work-in-progress clean_osm_data

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added clean links output to clean_osm_data. Script uses OSM relations to retrieve clean HVDC links.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* New code for integrating HVDC links. Using relations. Base network implementation functioning.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* removed manual line dropping.

* Updated clean script

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* reverted Snakefile to default: sync settings

* added prebuilt functionality.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Updated build_electricity.smk to work with scenario management.

* removed commented-out code.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* removed commented-out code.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fixed bug in pdf export by substituting pdf export with svg.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Bug-fix Snakefile

* dropped not needed columns from build_osm_network.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Updated build_shapes, config.default and clean_osm_data.

* pre-commit changes.

* test

* Added initial prepare_osm_network_release.py script

* Finalised prepare_osm_network_release script to build clean and stable OSM base_network input files.

* Added new rules/development.smk

* Updated clean_osm_data to add substation_centroid to linestrings

* Updated clean_osm_data to add substation_centroid to linestrings

* Updated clean_osm_data to add substation_centroid to linestrings

* Updated clean_osm_data to add substation_centroid to linestrings

* Added osm-prebuilt functionality and zenodo sandbox repository.

* Updated clean_osm_data to geopandas v.1.01

* Made base_network and build_osm_network function more robust for empty links.

* Made base_network and build_osm_network function more robust for empty links.

* Bug fix in base_network. Voltage level null is now kept (relevant e.g. for Corsica)

* Merge with hcanges in upstream PR 1146. Fixing UA and MD.

* Updated Zenodo and fixed prepare_osm_network_release

* Updated osm network release.

* Updated prepare osm network release.

* Updated MD, UA scripts.

* Cleaned determine_availability_matrix_MD_UA.py, removed redundant code

* Bug fixes.

* Bug fixes for UA MD scripts.

* Rename of build script.

* Bug fix: only distribute load to buses with substation.

* Updated zenodo sandbox repository.

* Updated config.default

* Cleaned config.default.yaml: Related settings grouped together and redundant voltage settings aggregated.

* Cleaned config.default.yaml: Related settings grouped together and redundant voltage settings aggregated. Added release notes.

* Updated Zenodo repositories for OSM-prebuilt to offcial publication.

* Updated configtables

* Updated links.csv: Under_construction lines to in commission.

* Updated link 8394 and parameter_corrections: Continuation of North-Sea-Link.

* Major update: fix simplify_network, fix Corsica, updated build_osm_network to include lines overpassing nodes.

* remove config backup

* Bug fix: Carrier type of all supernodes corrected to 'AC'

* Bug fix: Carrier type of all supernodes corrected to 'AC'

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Updated rules and base_network for compatibility with TYNDP projects.

* Updated Zenodo repository and prebuilt network to include 150 kV HVDC connections.

* Removed outdated config backup.

* Implemented all comments from PR #1079. Cleaned up OSM implementation.

* Bug fix: Added all voltages, 200 kV-750 kV, to default config.

* Cleaning and bugfixes.

* Updated Zenodo repository to https://zenodo.org/records/13358976. Added converter voltages, 'underground' property for DC lines/cables, and included Konti-Skan HVDC (DK-SE). Added compatibility with #1079 and #1085

* Apply suggestions from code review

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* simplify_network: handle complicated transformer topologies

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* syntax fix

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Fabian Neumann <fabian.neumann@outlook.de>
  • Loading branch information
3 people authored Aug 22, 2024
1 parent e273f4e commit 0c36de9
Show file tree
Hide file tree
Showing 14 changed files with 3,430 additions and 71 deletions.
1 change: 1 addition & 0 deletions Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ include: "rules/build_sector.smk"
include: "rules/solve_electricity.smk"
include: "rules/postprocess.smk"
include: "rules/validate.smk"
include: "rules/development.smk"


if config["foresight"] == "overnight":
Expand Down
7 changes: 4 additions & 3 deletions config/config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ scenario:
ll:
- vopt
clusters:
- 38
- 41
- 128
- 256
opts:
Expand Down Expand Up @@ -74,7 +74,6 @@ enable:
custom_busmap: false
drop_leap_day: true


# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#co2-budget
co2_budget:
2020: 0.701
Expand All @@ -87,7 +86,8 @@ co2_budget:

# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#electricity
electricity:
voltages: [220., 300., 380., 500., 750.]
voltages: [200., 220., 300., 380., 500., 750.]
base_network: entsoegridkit
gaslimit_enable: false
gaslimit: false
co2limit_enable: false
Expand Down Expand Up @@ -276,6 +276,7 @@ conventional:
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#lines
lines:
types:
200.: "Al/St 240/40 2-bundle 200.0"
220.: "Al/St 240/40 2-bundle 220.0"
300.: "Al/St 240/40 3-bundle 300.0"
380.: "Al/St 240/40 4-bundle 380.0"
Expand Down
3 changes: 2 additions & 1 deletion doc/configtables/electricity.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
,Unit,Values,Description
voltages,kV,"Any subset of {220., 300., 380.}",Voltage levels to consider
voltages,kV,"Any subset of {200., 220., 300., 380., 500., 750.}",Voltage levels to consider
base_network, --, "Any value in {'entsoegridkit', 'osm-prebuilt', 'osm-raw}", "Specify the underlying base network, i.e. GridKit (based on ENTSO-E web map extract, OpenStreetMap (OSM) prebuilt or raw (built from raw OSM data), takes longer."
gaslimit_enable,bool,true or false,Add an overall absolute gas limit configured in ``electricity: gaslimit``.
gaslimit,MWhth,float or false,Global gas usage limit
co2limit_enable,bool,true or false,Add an overall absolute carbon-dioxide emissions limit configured in ``electricity: co2limit`` in :mod:`prepare_network`. **Warning:** This option should currently only be used with electricity-only networks, not for sector-coupled networks..
Expand Down
2 changes: 2 additions & 0 deletions doc/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ Upcoming Release

* Enable parallelism in :mod:`determine_availability_matrix_MD_UA.py` and remove plots. This requires the use of temporary files.

* Added new major feature to create the base_network from OpenStreetMap (OSM) data (PR https://github.com/PyPSA/pypsa-eur/pull/1079). Note that a heuristics based cleaning process is used for lines and links where electrical parameters are incomplete, missing, or ambiguous. Through ``electricity["base_network"]``, the base network can be set to "entsoegridkit" (original default setting, deprecated soon), "osm-prebuilt" (which downloads the latest prebuilt snapshot based on OSM data from Zenodo), or "osm-raw" which retrieves (once) and cleans the raw OSM data and subsequently builds the network. Note that this process may take a few minutes.

* Updated pre-built `weather data cutouts
<https://zenodo.org/records/12791128>`__. These are now merged cutouts with
solar irradiation from the new SARAH-3 dataset while taking all other
Expand Down
1 change: 1 addition & 0 deletions envs/environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies:
- pyxlsb
- graphviz
- pre-commit
- geojson

# Keep in conda environment when calling ipython
- ipython
Expand Down
97 changes: 90 additions & 7 deletions rules/build_electricity.smk
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ rule build_powerplants:
"../scripts/build_powerplants.py"


def input_base_network(w):
base_network = config_provider("electricity", "base_network")(w)
components = {"buses", "lines", "links", "converters", "transformers"}
if base_network == "osm-raw":
inputs = {c: resources(f"osm-raw/build/{c}.csv") for c in components}
else:
inputs = {c: f"data/{base_network}/{c}.csv" for c in components}
if base_network == "entsoegridkit":
inputs["parameter_corrections"] = "data/parameter_corrections.yaml"
inputs["links_p_nom"] = "data/links_p_nom.csv"
return inputs


rule base_network:
params:
countries=config_provider("countries"),
Expand All @@ -58,13 +71,7 @@ rule base_network:
lines=config_provider("lines"),
transformers=config_provider("transformers"),
input:
eg_buses="data/entsoegridkit/buses.csv",
eg_lines="data/entsoegridkit/lines.csv",
eg_links="data/entsoegridkit/links.csv",
eg_converters="data/entsoegridkit/converters.csv",
eg_transformers="data/entsoegridkit/transformers.csv",
parameter_corrections="data/parameter_corrections.yaml",
links_p_nom="data/links_p_nom.csv",
unpack(input_base_network),
country_shapes=resources("country_shapes.geojson"),
offshore_shapes=resources("offshore_shapes.geojson"),
europe_shape=resources("europe_shape.geojson"),
Expand Down Expand Up @@ -629,3 +636,79 @@ rule prepare_network:
"../envs/environment.yaml"
script:
"../scripts/prepare_network.py"


if config["electricity"]["base_network"] == "osm-raw":

rule clean_osm_data:
input:
cables_way=expand(
"data/osm-raw/{country}/cables_way.json",
country=config_provider("countries"),
),
lines_way=expand(
"data/osm-raw/{country}/lines_way.json",
country=config_provider("countries"),
),
links_relation=expand(
"data/osm-raw/{country}/links_relation.json",
country=config_provider("countries"),
),
substations_way=expand(
"data/osm-raw/{country}/substations_way.json",
country=config_provider("countries"),
),
substations_relation=expand(
"data/osm-raw/{country}/substations_relation.json",
country=config_provider("countries"),
),
offshore_shapes=resources("offshore_shapes.geojson"),
country_shapes=resources("country_shapes.geojson"),
output:
substations=resources("osm-raw/clean/substations.geojson"),
substations_polygon=resources("osm-raw/clean/substations_polygon.geojson"),
lines=resources("osm-raw/clean/lines.geojson"),
links=resources("osm-raw/clean/links.geojson"),
log:
logs("clean_osm_data.log"),
benchmark:
benchmarks("clean_osm_data")
threads: 1
resources:
mem_mb=4000,
conda:
"../envs/environment.yaml"
script:
"../scripts/clean_osm_data.py"


if config["electricity"]["base_network"] == "osm-raw":

rule build_osm_network:
input:
substations=resources("osm-raw/clean/substations.geojson"),
lines=resources("osm-raw/clean/lines.geojson"),
links=resources("osm-raw/clean/links.geojson"),
country_shapes=resources("country_shapes.geojson"),
output:
lines=resources("osm-raw/build/lines.csv"),
links=resources("osm-raw/build/links.csv"),
converters=resources("osm-raw/build/converters.csv"),
transformers=resources("osm-raw/build/transformers.csv"),
substations=resources("osm-raw/build/buses.csv"),
lines_geojson=resources("osm-raw/build/geojson/lines.geojson"),
links_geojson=resources("osm-raw/build/geojson/links.geojson"),
converters_geojson=resources("osm-raw/build/geojson/converters.geojson"),
transformers_geojson=resources("osm-raw/build/geojson/transformers.geojson"),
substations_geojson=resources("osm-raw/build/geojson/buses.geojson"),
log:
logs("build_osm_network.log"),
benchmark:
benchmarks("build_osm_network")
threads: 1
resources:
mem_mb=4000,
conda:
"../envs/environment.yaml"
script:
"../scripts/build_osm_network.py"
26 changes: 26 additions & 0 deletions rules/development.smk
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: : 2023-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT

if config["electricity"]["base_network"] == "osm-raw":

rule prepare_osm_network_release:
input:
base_network=resources("networks/base.nc"),
output:
buses=resources("osm-raw/release/buses.csv"),
converters=resources("osm-raw/release/converters.csv"),
lines=resources("osm-raw/release/lines.csv"),
links=resources("osm-raw/release/links.csv"),
transformers=resources("osm-raw/release/transformers.csv"),
log:
logs("prepare_osm_network_release.log"),
benchmark:
benchmarks("prepare_osm_network_release")
threads: 1
resources:
mem_mb=1000,
conda:
"../envs/environment.yaml"
script:
"../scripts/prepare_osm_network_release.py"
82 changes: 82 additions & 0 deletions rules/retrieve.smk
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,85 @@ if config["enable"]["retrieve"]:
"../envs/retrieve.yaml"
script:
"../scripts/retrieve_monthly_fuel_prices.py"


if config["enable"]["retrieve"] and (
config["electricity"]["base_network"] == "osm-prebuilt"
):

rule retrieve_osm_prebuilt:
input:
buses=storage("https://zenodo.org/records/13358976/files/buses.csv"),
converters=storage(
"https://zenodo.org/records/13358976/files/converters.csv"
),
lines=storage("https://zenodo.org/records/13358976/files/lines.csv"),
links=storage("https://zenodo.org/records/13358976/files/links.csv"),
transformers=storage(
"https://zenodo.org/records/13358976/files/transformers.csv"
),
output:
buses="data/osm-prebuilt/buses.csv",
converters="data/osm-prebuilt/converters.csv",
lines="data/osm-prebuilt/lines.csv",
links="data/osm-prebuilt/links.csv",
transformers="data/osm-prebuilt/transformers.csv",
log:
"logs/retrieve_osm_prebuilt.log",
threads: 1
resources:
mem_mb=500,
retries: 2
run:
for key in input.keys():
move(input[key], output[key])
validate_checksum(output[key], input[key])



if config["enable"]["retrieve"] and (
config["electricity"]["base_network"] == "osm-raw"
):

rule retrieve_osm_data:
output:
cables_way="data/osm-raw/{country}/cables_way.json",
lines_way="data/osm-raw/{country}/lines_way.json",
links_relation="data/osm-raw/{country}/links_relation.json",
substations_way="data/osm-raw/{country}/substations_way.json",
substations_relation="data/osm-raw/{country}/substations_relation.json",
log:
"logs/retrieve_osm_data_{country}.log",
threads: 1
conda:
"../envs/retrieve.yaml"
script:
"../scripts/retrieve_osm_data.py"


if config["enable"]["retrieve"] and (
config["electricity"]["base_network"] == "osm-raw"
):

rule retrieve_osm_data_all:
input:
expand(
"data/osm-raw/{country}/cables_way.json",
country=config_provider("countries"),
),
expand(
"data/osm-raw/{country}/lines_way.json",
country=config_provider("countries"),
),
expand(
"data/osm-raw/{country}/links_relation.json",
country=config_provider("countries"),
),
expand(
"data/osm-raw/{country}/substations_way.json",
country=config_provider("countries"),
),
expand(
"data/osm-raw/{country}/substations_relation.json",
country=config_provider("countries"),
),
Loading

0 comments on commit 0c36de9

Please sign in to comment.