From db5b2137c00a9670f7c0e0aabbb4c2d59a6aa71b Mon Sep 17 00:00:00 2001 From: IlkaCu Date: Fri, 21 Jul 2023 13:18:45 +0200 Subject: [PATCH 1/2] Add data sets descriptions --- .../data/datasets/demandregio/__init__.py | 34 +++++++++- .../datasets/electricity_demand/__init__.py | 62 +++++++++++++++++-- .../datasets/electricity_demand_etrago.py | 30 ++++++++- src/egon/data/datasets/industry/__init__.py | 37 ++++++++++- src/egon/data/datasets/osmtgmod/__init__.py | 54 ++++++++++++---- src/egon/data/datasets/storages/__init__.py | 40 +++++++++++- .../data/datasets/storages_etrago/__init__.py | 37 ++++++++++- 7 files changed, 265 insertions(+), 29 deletions(-) diff --git a/src/egon/data/datasets/demandregio/__init__.py b/src/egon/data/datasets/demandregio/__init__.py index 6d8ff5810..495940df7 100644 --- a/src/egon/data/datasets/demandregio/__init__.py +++ b/src/egon/data/datasets/demandregio/__init__.py @@ -32,10 +32,40 @@ class DemandRegio(Dataset): + """ + Extract and adjust data from DemandRegio + + Demand data for the sectors households, CTS and industry are calculated + using DemandRegio's diaggregator and input data. To bring the resulting + data in line with other data used in eGon-data and the eGon project in + general some data needed to be adjusted or extended, e.g. in function + :py:func:`adjust_ind_pes` or function :py:func:`adjust_cts_ind_nep`. The + resulting data is written into newly created tables. + + *Dependencies* + * :py:class:`DataBundle ` + * :py:class:`ScenarioParameters ` + * :py:class:`ZensusVg250 ` + + *Resulting tables* + * :py:class:`demand.egon_demandregio_hh ` is created and filled + * :py:class:`demand.egon_demandregio_cts_ind ` is created and filled + * :py:class:`society.egon_demandregio_population ` is created and filled + * :py:class:`society.egon_demandregio_household ` is created and filled + * :py:class:`demand.egon_demandregio_wz ` is created and filled + * :py:class:`demand.egon_demandregio_timeseries_cts_ind ` is created and filled + + """ + + #: + name: str = "DemandRegio" + #: + version: str = "0.0.5" + def __init__(self, dependencies): super().__init__( - name="DemandRegio", - version="0.0.5", + name=self.name, + version=self.version, dependencies=dependencies, tasks=( clone_and_install, diff --git a/src/egon/data/datasets/electricity_demand/__init__.py b/src/egon/data/datasets/electricity_demand/__init__.py index 067ca90f6..0eb0f5664 100644 --- a/src/egon/data/datasets/electricity_demand/__init__.py +++ b/src/egon/data/datasets/electricity_demand/__init__.py @@ -25,20 +25,74 @@ class HouseholdElectricityDemand(Dataset): + """ + Create table and store data on household electricity demands per census cell + + Create a table to store the annual electricity demand for households on census cell level. + In a next step the annual electricity demand per cell is determined by + executing function :py:func:`get_annual_household_el_demand_cells` + + *Dependencies* + * :py:class:`DemandRegio ` + * :py:class:`DataBundle ` + + *Resulting tables* + * :py:class:`demand.egon_demandregio_zensus_electricity ` is created and filled + + """ + + #: + name: str = "HouseholdElectricityDemand" + #: + version: str = "0.0.3" + def __init__(self, dependencies): super().__init__( - name="HouseholdElectricityDemand", - version="0.0.3", + name=self.name, + version=self.version, dependencies=dependencies, tasks=(create_tables, get_annual_household_el_demand_cells), ) class CtsElectricityDemand(Dataset): + """ + Create table and store data on cts electricity demands per census cell + + Creates a table to store data on electricity demands from the cts sector on + census cell level. For a spatial distribution of electricity demands data + from DemandRegio, which provides the data on NUT3-level, is used and + distributed to census cells according to heat demand data from Peta. + Annual demands are then aggregated per MV grid district and a corresponding + time series is created taking the shares of different cts branches and their + specific standard load profiles into account. + + + *Dependencies* + * :py:class:`MapZensusGridDistricts ` + * :py:class:`DemandRegio ` + * :py:class:`HeatDemandImport ` + * :py:class:`HouseholdElectricityDemand ` + * :py:class:`EtragoSetup ` + * :py:class:`ZensusMvGridDistricts ` + * :py:class:`ZensusVg250 ` + + + *Resulting tables* + * :py:class:`demand.egon_etrago_electricity_cts ` is created and filled + + + """ + + #: + name: str = "CtsElectricityDemand" + #: + version: str = "0.0.2" + def __init__(self, dependencies): super().__init__( - name="CtsElectricityDemand", - version="0.0.2", + name=self.name, + version=self.version, dependencies=dependencies, tasks=(distribute_cts_demands, insert_cts_load), ) diff --git a/src/egon/data/datasets/electricity_demand_etrago.py b/src/egon/data/datasets/electricity_demand_etrago.py index 65b50a2a0..545346b92 100644 --- a/src/egon/data/datasets/electricity_demand_etrago.py +++ b/src/egon/data/datasets/electricity_demand_etrago.py @@ -183,7 +183,7 @@ def export_to_db(): WHERE scn_name = '{scenario}' AND carrier = 'AC' AND bus IN ( - SELECT bus_id FROM + SELECT bus_id FROM {sources['etrago_buses']['schema']}. {sources['etrago_buses']['table']} WHERE country = 'DE' @@ -268,10 +268,34 @@ def export_to_db(): class ElectricalLoadEtrago(Dataset): + """ + Aggregate annual and hourly electricity demands per substation and export + to eTraGo tables + + All loads including time series are aggregated per corresponding substation + and inserted into the existing eTraGo tables. Additionally the aggregated + national time series are stored to function as an input for pypsa-eur-sec. + + + *Dependencies* + * :py:class:`CtsElectricityDemand ` + * :py:class:`IndustrialDemandCurves ` + * :py:class:`hh_buildings ` + + *Resulting tables* + * :py:class:`grid.egon_etrago_load ` is extended + * :py:class:`grid.egon_etrago_load_timeseries ` is extended + """ + + #: + name: str = "Electrical_load_etrago" + #: + version: str = "0.0.6" + def __init__(self, dependencies): super().__init__( - name="Electrical_load_etrago", - version="0.0.6", + name=self.name, + version=self.version, dependencies=dependencies, tasks=(export_to_db,), ) diff --git a/src/egon/data/datasets/industry/__init__.py b/src/egon/data/datasets/industry/__init__.py index bb4f0fb22..2f03211c1 100644 --- a/src/egon/data/datasets/industry/__init__.py +++ b/src/egon/data/datasets/industry/__init__.py @@ -407,10 +407,43 @@ def industrial_demand_distr(): class IndustrialDemandCurves(Dataset): + """ + Distribute industrial electricity demands to industrial sites and OSM + landuse areas + + Creates different tables to store industrial electricity demand curves on + different aggregation levels. In a first step industrial demands taken from + DemandRegio are distributed to industrial sites and OSM polygons which are + tagged as industrial areas. This method takes information on the different + industrial sectors into account and allocates the annual demand as well as + load curves accordingly. + + *Dependencies* + * :py:class:`DemandRegio ` + * :py:class:`MergeIndustrialSites ` + * :py:class:`OsmLanduse ` + * :py:func:`define_mv_grid_districts ` + * :py:class:`OpenStreetMap ` + + *Resulting tables* + * :py:class:`demand.egon_demandregio_osm_ind_electricity ` is created and filled + * :py:class:`demand.egon_demandregio_sites_ind_electricity ` is created and filled + * :py:class:`demand.egon_osm_ind_load_curves ` is created and filled + * :py:class:`demand.egon_osm_ind_load_curves_individual ` is created and filled + * :py:class:`demand.egon_sites_ind_load_curves ` is created and filled + * :py:class:`demand.egon_sites_ind_load_curves_individual ` is created and filled + + """ + + #: + name: str = "Industrial_demand_curves" + #: + version: str = "0.0.5" + def __init__(self, dependencies): super().__init__( - name="Industrial_demand_curves", - version="0.0.5", + name=self.name, + version=self.version, dependencies=dependencies, tasks=( create_tables, diff --git a/src/egon/data/datasets/osmtgmod/__init__.py b/src/egon/data/datasets/osmtgmod/__init__.py index eed93bc76..e9bc7b760 100644 --- a/src/egon/data/datasets/osmtgmod/__init__.py +++ b/src/egon/data/datasets/osmtgmod/__init__.py @@ -627,19 +627,19 @@ def to_pypsa(): WHERE a.line_id = result.line_id AND scn_name = {scenario_name}; - -- set capital costs for eHV-lines + -- set capital costs for eHV-lines UPDATE grid.egon_etrago_line SET capital_cost = {capital_cost['ac_ehv_overhead_line']} * length WHERE v_nom > 110 AND scn_name = {scenario_name}; - -- set capital costs for HV-lines + -- set capital costs for HV-lines UPDATE grid.egon_etrago_line SET capital_cost = {capital_cost['ac_hv_overhead_line']} * length WHERE v_nom = 110 AND scn_name = {scenario_name}; - - -- set capital costs for transformers + + -- set capital costs for transformers UPDATE grid.egon_etrago_transformer a SET capital_cost = {capital_cost['transformer_380_220']} WHERE (a.bus0 IN ( @@ -687,20 +687,20 @@ def to_pypsa(): SELECT bus_id FROM grid.egon_etrago_bus WHERE v_nom = 220)) AND scn_name = {scenario_name}; - - -- set lifetime for eHV-lines + + -- set lifetime for eHV-lines UPDATE grid.egon_etrago_line - SET lifetime = {lifetime['ac_ehv_overhead_line']} + SET lifetime = {lifetime['ac_ehv_overhead_line']} WHERE v_nom > 110 AND scn_name = {scenario_name}; - -- set capital costs for HV-lines + -- set capital costs for HV-lines UPDATE grid.egon_etrago_line SET lifetime = {lifetime['ac_hv_overhead_line']} WHERE v_nom = 110 AND scn_name = {scenario_name}; - - -- set capital costs for transformers + + -- set capital costs for transformers UPDATE grid.egon_etrago_transformer a SET lifetime = {lifetime['transformer_380_220']} WHERE (a.bus0 IN ( @@ -748,7 +748,7 @@ def to_pypsa(): SELECT bus_id FROM grid.egon_etrago_bus WHERE v_nom = 220)) AND scn_name = {scenario_name}; - + -- delete buses without connection to AC grid and generation or -- load assigned @@ -772,10 +772,38 @@ def to_pypsa(): class Osmtgmod(Dataset): + """ + Run the tool osmtgmod to generate transmission grid topology + + Executes the tool osmtgmod which create a electricity grid topology based + on OSM data for the voltage levels 110 - 380 kV. For further information + on osmtgmod please refer our `osmtgmod fork. `_ + Standard electrical line parameters are added to the grid topology and + resulting data on buses, lines and transformers are exported to the data + base. + + *Dependencies* + * :py:class:`ScenarioParameters ` + * :py:class:`EtragoSetup ` + * :py:class:`SubstationExtraction ` + * :py:class:`OpenStreetMap ` + + *Resulting tables* + * :py:class:`grid.egon_etrago_bus ` is extended + * :py:class:`grid.egon_etrago_line ` is extended + * :py:class:`grid.egon_etrago_transformer ` is extended + + """ + + #: + name: str = "Osmtgmod" + #: + version: str = "0.0.5" + def __init__(self, dependencies): super().__init__( - name="Osmtgmod", - version="0.0.5", + name=self.name, + version=self.version, dependencies=dependencies, tasks=( import_osm_data, diff --git a/src/egon/data/datasets/storages/__init__.py b/src/egon/data/datasets/storages/__init__.py index f503d4e85..4b94655ca 100755 --- a/src/egon/data/datasets/storages/__init__.py +++ b/src/egon/data/datasets/storages/__init__.py @@ -43,10 +43,46 @@ class EgonStorages(Base): class Storages(Dataset): + """ + Allocates storage units such as pumped hydro and home batteries + + This data set creates interim tables to store information on storage units. + In addition the target value for the installed capacity of pumped hydro + storage units are spatially allocated using information of existing plants + from the official registry Markstammdatenregister. After allocating the + plants missing information such as the voltage level and the correct grid + connection point are added. + This data set also allocates the target value of home batteries spatially + on different aggregation levels. In a first step function + :py:func:`allocate_pv_home_batteries_to_grids` spatially distributes the + installed battery capacities to all mv grid districts based on their + installed pv rooftop capacity. + Function :py:func:`allocate_home_batteries_to_buildings` further + distributes the home battery storage systems to buildings with pv + rooftop systems. + + *Dependencies* + * :py:func:`download_mastr_data ` + * :py:func:`define_mv_grid_districts ` + * :py:class: `PowerPlants ` + * :py:class:`ScenarioCapacities ` + * :py:class:`ScenarioParameters ` + * :py:class:`Vg250MvGridDistricts ` + + *Resulting tables* + * :py:class:`supply.egon_storages ` + + """ + + #: + name: str = "Storages" + #: + version: str = "0.0.4" + def __init__(self, dependencies): super().__init__( - name="Storages", - version="0.0.4", + name=self.name, + version=self.version, dependencies=dependencies, tasks=( create_tables, diff --git a/src/egon/data/datasets/storages_etrago/__init__.py b/src/egon/data/datasets/storages_etrago/__init__.py index 3382c62ff..67755a770 100644 --- a/src/egon/data/datasets/storages_etrago/__init__.py +++ b/src/egon/data/datasets/storages_etrago/__init__.py @@ -15,15 +15,46 @@ class StorageEtrago(Dataset): + """ + Adds pumped hydro storage units and extendable batteries to the data base + + This data sets adds storage unit to the data base used for transmission + grid optimisation with the tool eTraGo. In a first step pumped hydro + storage units for Germany are taken from an interim table and technical + parameters such as standing losses, efficiency and max_hours are added. + Afterwards the data is written to the correct tables which are accessed by + eTraGo. + In a next step batteries are added. On the one hand these are home + batteries, assumptions on their capacity and distribution is taken from an + other interim table. In addition extendable batteries with an installed + capacity of 0 are added to every substation to allow a battery expansion in + eTraGo. For all batteries assumptions on technical parameters are added. + The resulting data is written to the corresponding tables in the data base. + + *Dependencies* + * :py:class:`Storages ` + * :py:class:`ScenarioParameters ` + * :py:class:`EtragoSetup ` + + *Resulting tables* + * :py:class:`grid.egon_etrago_storage ` is extended + + """ + + #: + name: str = "StorageEtrago" + #: + version: str = "0.0.8" + + def __init__(self, dependencies): super().__init__( - name="StorageEtrago", - version="0.0.8", + name=self.name, + version=self.version, dependencies=dependencies, tasks=(insert_PHES, extendable_batteries), ) - def insert_PHES(): # Get datasets configuration From db39e929d45f23163c66d46d2e5d29324eefe372 Mon Sep 17 00:00:00 2001 From: IlkaCu Date: Mon, 7 Aug 2023 10:08:52 +0200 Subject: [PATCH 2/2] Add first documentation for pp dataset --- .../data/datasets/power_plants/__init__.py | 71 ++++++++++++++++++- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/egon/data/datasets/power_plants/__init__.py b/src/egon/data/datasets/power_plants/__init__.py index 71213e66f..ac38a54a1 100755 --- a/src/egon/data/datasets/power_plants/__init__.py +++ b/src/egon/data/datasets/power_plants/__init__.py @@ -1,4 +1,5 @@ -"""The central module containing all code dealing with power plant data. +"""The central module containing all code dealing with tge distribution and +allocation of data on conventional and renewable power plants. """ from geoalchemy2 import Geometry from sqlalchemy import BigInteger, Column, Float, Integer, Sequence, String @@ -56,10 +57,65 @@ class EgonPowerPlants(Base): class PowerPlants(Dataset): + """ + This dataset deals with the distribution and allocation of power plants + + For the distribution and allocation of power plants to their corresponding + grid connection point different technology-specific methods are applied. + In a first step separate tables are created for wind, pv, hydro and biomass + based power plants by running :py:func:`create_tables`. + Different methods rely on the locations of existing power plants retrieved + from the official power plant registry 'Marktstammdatenregister' applying + function :py:func:`ìmport_mastr`. + + *Hydro and Biomass* + Hydro and biomass power plants are distributed based on the status quo + locations of existing power plants assuming that no further expansion of + these technologies is to be expected in Germany. Hydro power plants include + reservoir and run-of-river plants. + Power plants without a correct geolocation are not taken into account. + To compensate this, the installed capacities of the suitable plants are + scaled up to meet the target value using function :py:func:`scale_prox2now` + + *Conventional power plants without CHP* + The distribution of conventional plants, excluding CHPs, takes place in + function :py:func:`allocate_conventional_non_chp_power_plants`. Therefore + information about future power plants from the grid development plan + function as the target value and are matched with actual existing power + plants with correct geolocations from MaStR registry. + + *Wind onshore* + + + *Wind offshore* + + *PV ground-mounted* + + *PV rooftop* + + *others* + + + + + + *Dependencies* + * :py:class:` <>` + + *Resulting tables* + * :py:class:` <>` is extended + + """ + + #: + name: str = "PowerPlants" + #: + version: str = "0.0.18" + def __init__(self, dependencies): super().__init__( - name="PowerPlants", - version="0.0.18", + name=self.name, + version=self.version, dependencies=dependencies, tasks=( create_tables, @@ -610,6 +666,15 @@ def insert_hydro_biomass(): def allocate_conventional_non_chp_power_plants(): + """Allocate conventional power plants without CHPs based on the NEP target + values and data from power plant registry (MaStR) by assigning them in a + cascaded manner. + + Returns + ------- + None. + + """ carrier = ["oil", "gas"]