pypsa-eur/scripts/build_monthly_prices.py

121 lines
3.2 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
2024-02-19 15:21:48 +00:00
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
2023-05-16 11:49:03 +00:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
This script extracts monthly fuel prices of oil, gas, coal and lignite, as well
as CO2 prices.
2023-05-16 11:49:03 +00:00
Inputs
------
- ``data/energy-price-trends-xlsx-5619002.xlsx``: energy price index of fossil fuels
- ``emission-spot-primary-market-auction-report-2019-data.xls``: CO2 Prices spot primary auction
Outputs
-------
- ``data/validation/monthly_fuel_price.csv``
- ``data/validation/CO2_price_2019.csv``
Description
-----------
The rule :mod:`build_monthly_prices` collects monthly fuel prices and CO2 prices
and translates them from different input sources to pypsa syntax
Data sources:
[1] Fuel price index. Destatis
https://www.destatis.de/EN/Home/_node.html
[2] average annual fuel price lignite, ENTSO-E
2023-05-16 11:49:03 +00:00
https://2020.entsos-tyndp-scenarios.eu/fuel-commodities-and-carbon-prices/
[3] CO2 Prices, Emission spot primary auction, EEX
2023-05-16 11:49:03 +00:00
https://www.eex.com/en/market-data/environmental-markets/eua-primary-auction-spot-download
Data was accessed at 16.5.2023
"""
import logging
import pandas as pd
2023-08-15 13:02:41 +00:00
from _helpers import configure_logging, set_scenario_config
2023-05-16 11:49:03 +00:00
logger = logging.getLogger(__name__)
# keywords in datasheet
keywords = {
"coal": " GP09-051 Hard coal",
"lignite": " GP09-052 Lignite and lignite briquettes",
"oil": " GP09-0610 10 Mineral oil, crude",
"gas": "GP09-062 Natural gas",
}
2023-05-16 11:49:03 +00:00
# sheet names to pypsa syntax
sheet_name_map = {
"coal": "5.1 Hard coal and lignite",
"lignite": "5.1 Hard coal and lignite",
"oil": "5.2 Mineral oil",
"gas": "5.3.1 Natural gas - indices",
}
2023-05-16 11:49:03 +00:00
# import fuel price 2015 in Eur/MWh
# source lignite, price for 2020, scaled by price index, ENTSO-E [3]
price_2020 = (
pd.Series({"coal": 3.0, "oil": 10.6, "gas": 5.6, "lignite": 1.1}) * 3.6
) # Eur/MWh
# manual adjustment of coal price
price_2020["coal"] = 2.4 * 3.6
price_2020["lignite"] = 1.6 * 3.6
2023-07-31 09:15:21 +00:00
2023-05-16 11:49:03 +00:00
def get_fuel_price():
price = {}
2023-05-16 11:49:03 +00:00
for carrier, keyword in keywords.items():
sheet_name = sheet_name_map[carrier]
df = pd.read_excel(
snakemake.input.fuel_price_raw,
sheet_name=sheet_name,
index_col=0,
skiprows=6,
nrows=18,
)
df = df.dropna(axis=0).iloc[:, :12]
start, end = df.index[0], str(int(df.index[-1][:4]) + 1)
df = df.stack()
df.index = pd.date_range(start=start, end=end, freq="MS", inclusive="left")
scale = price_2020[carrier] / df["2020"].mean() # scale to 2020 price
df = df.mul(scale)
price[carrier] = df
return pd.concat(price, axis=1)
2023-05-16 11:49:03 +00:00
2023-05-16 11:49:03 +00:00
def get_co2_price():
# emission price
co2_price = pd.read_excel(snakemake.input.co2_price_raw, index_col=1, header=5)
return co2_price["Auction Price €/tCO2"]
2023-05-16 11:49:03 +00:00
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
2023-05-16 11:49:03 +00:00
snakemake = mock_snakemake("build_monthly_prices")
2023-05-16 11:49:03 +00:00
configure_logging(snakemake)
2023-08-15 13:02:41 +00:00
set_scenario_config(snakemake)
fuel_price = get_fuel_price()
fuel_price.to_csv(snakemake.output.fuel_price)
co2_price = get_co2_price()
co2_price.to_csv(snakemake.output.co2_price)