Skip to content

Commit

Permalink
Merge 957c605 into fda4202
Browse files Browse the repository at this point in the history
  • Loading branch information
uvchik committed Nov 12, 2019
2 parents fda4202 + 957c605 commit 5148c5f
Show file tree
Hide file tree
Showing 17 changed files with 654 additions and 187 deletions.
392 changes: 290 additions & 102 deletions deflex/basic_scenario.py

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions deflex/de21_default.ini_backup
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ scenario = local_root, scenarios
deflex_feedin = local_root, data, feedin, {map}_region, {year}

[geometry]
germany_polygon = germany_polygon.csv
deflex_polygon = region_{type}_{map}_{suffix}.csv
region_polygon_simple = region_polygons_{map}_simple.csv
region_label = region_labels_{map}.csv
Expand Down Expand Up @@ -77,7 +76,7 @@ readme_file = timeseries_readme.md
json_file = timeseries_datapackage.json

[heating]
table = decentralised_heating.csv
table = scenario_decentralised_heat.csv

[demand]
ego_file_deflex = oep_ego_demand_{map}.h5
Expand Down
7 changes: 3 additions & 4 deletions deflex/deflex.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ scenario = local_root, scenarios
deflex_feedin = local_root, data, feedin, {map}_region, {year}

[geometry]
germany_polygon = germany_polygon.csv
deflex_polygon = region_{type}_{map}{suffix}
region_polygon_simple = region_polygons_{map}_simple.csv
region_label = region_labels_{map}.csv
Expand Down Expand Up @@ -55,8 +54,8 @@ commodity_sources_file = commodity_sources.csv
renewable_source = bioenergy

[feedin]
feedin_deflex_pattern = {year}_feedin_{map}_region_normalised_{type}.csv
feedin_deflex_pattern_var = {year}_feedin_{map}_region_normalised_{type}_var_{weather_year}.csv
feedin_deflex_pattern = {year}_feedin_{map}_normalised_{type}.csv
feedin_deflex_pattern_var = {year}_feedin_{map}_normalised_{type}_var_{weather_year}.csv
geothermal_full_load_hours = 4380

[time_series]
Expand All @@ -68,7 +67,7 @@ readme_file = timeseries_readme.md
json_file = timeseries_datapackage.json

[heating]
table = decentralised_heating.csv
table = scenario_decentralised_heat.csv

[demand_heat]
heat_profile_region = heat_profile_{map}_{year}.csv
Expand Down
4 changes: 2 additions & 2 deletions deflex/demand.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from reegis import demand_heat


def get_heat_profiles_deflex(year, deflex_geo, time_index=None,
def get_heat_profiles_deflex(deflex_geo, year, time_index=None,
weather_year=None, keep_unit=False):
"""
Expand Down Expand Up @@ -49,7 +49,7 @@ def get_heat_profiles_deflex(year, deflex_geo, time_index=None,
'heat_profiles_{year}_{map}'.format(year=year, map=deflex_geo.name))

demand_region = demand_heat.get_heat_profiles_by_region(
year, deflex_geo, to_csv=fn, weather_year=weather_year).groupby(
deflex_geo, year, to_csv=fn, weather_year=weather_year).groupby(
level=[0, 1], axis=1).sum()

# Decentralised demand is combined to a nation-wide demand if not part
Expand Down
41 changes: 41 additions & 0 deletions deflex/geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

# Python libraries
import os
from collections import namedtuple

# Internal libraries
from deflex import config as cfg
Expand Down Expand Up @@ -91,3 +92,43 @@ def deflex_power_lines(rmap=None, rtype='lines'):
lines.set_index('name', inplace=True)
lines.name = rmap
return lines


def divide_off_and_onshore(regions):
"""
Sort regions into onshore and offshore regions. A namedtuple with two list
of regions ids will be returned. Fetch the `onshore` and `offshore`
attribute of the named tuple to get the list.
Parameters
----------
regions : GeoDataFrame
A region set with the region id in the index.
Returns
-------
named tuple
Examples
--------
>>> reg = deflex_regions('de02')
>>> divide_off_and_onshore(reg).onshore
['DE01']
>>> reg = deflex_regions('de21')
>>> divide_off_and_onshore(reg).offshore
['DE19', 'DE20', 'DE21']
"""
region_type = namedtuple('RegionType', 'offshore onshore')
regions.geometry = regions.centroid

germany_onshore = geo.load(
cfg.get('paths', 'geometry'),
cfg.get('geometry', 'germany_polygon'))

gdf = geo.spatial_join_with_buffer(regions, germany_onshore,
'onshore', limit=0)

onshore = list(gdf.loc[gdf.onshore == 0].index)
offshore = list(gdf.loc[gdf.onshore == 'unknown'].index)

return region_type(offshore=offshore, onshore=onshore)
15 changes: 7 additions & 8 deletions deflex/powerplants.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@
from reegis import geometries as reegis_geometries
from reegis import config as cfg
from reegis import powerplants
from deflex import geometries


# Todo: Revise and test.


def pp_reegis2deflex(filename_in=None, filename_out=None):
def pp_reegis2deflex(regions, name, filename_in=None, filename_out=None):
"""
Add federal states and deflex regions to powerplant table from reegis. As
the process takes a while the result is stored for further usage.
Expand All @@ -39,10 +38,8 @@ def pp_reegis2deflex(filename_in=None, filename_out=None):
map=cfg.get('init', 'map'))

# Add deflex regions to powerplants
deflex_regions = geometries.deflex_regions()
name = '{0}_region'.format(cfg.get('init', 'map'))
pp = powerplants.add_regions_to_powerplants(
deflex_regions, name, dump=False, filename=filename_in)
regions, name, dump=False, filename=filename_in)

# Add federal states to powerplants
federal_states = reegis_geometries.get_federal_states_polygon()
Expand Down Expand Up @@ -115,12 +112,14 @@ def process_pp_table(pp):
return pp


def get_deflex_pp_by_year(year, overwrite_capacity=False):
def get_deflex_pp_by_year(regions, year, name, overwrite_capacity=False):
"""
Parameters
----------
regions : GeoDataFrame
year : int
name : str
overwrite_capacity : bool
By default (False) a new column "capacity_<year>" is created. If set to
True the old capacity column will be overwritten.
Expand All @@ -131,12 +130,12 @@ def get_deflex_pp_by_year(year, overwrite_capacity=False):
"""
filename = os.path.join(cfg.get('paths', 'powerplants'),
cfg.get('powerplants', 'deflex_pp')).format(
map=cfg.get('init', 'map'))
map=name)
logging.info("Get deflex power plants for {0}.".format(year))
if not os.path.isfile(filename):
msg = "File '{0}' does not exist. Will create it from reegis file."
logging.debug(msg.format(filename))
filename = pp_reegis2deflex()
filename = pp_reegis2deflex(regions, name)
pp = pd.DataFrame(pd.read_hdf(filename, 'pp', mode='r'))

# Remove unwanted data sets
Expand Down
2 changes: 1 addition & 1 deletion deflex/scenario_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def add_decentralised_heating_systems(table_collection, nodes, extra_regions):
logging.debug("Add decentralised_heating_systems to nodes dictionary.")
cs = table_collection['commodity_source']['DE']
dts = table_collection['demand_series']
dh = table_collection['decentralised_heating']
dh = table_collection['decentralised_heat']
demand_regions = list({'DE_demand'}.union(set(extra_regions)))

for d_region in demand_regions:
Expand Down
166 changes: 128 additions & 38 deletions deflex/transmission.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@


def get_grid_capacity(grid, plus, minus):
"""Read the grid capacity from a given region pair from the renpass db."""
tmp_grid = grid.query("plus_region_id == {:0d} & ".format(plus) +
"minus_region_id == {:1d} & ".format(minus) +
"scenario_name == 'status_quo_2012_distance'")
Expand All @@ -37,48 +38,145 @@ def get_grid_capacity(grid, plus, minus):
return capacity, distance


def get_electrical_transmission_deflex(duplicate=False):
renpas_maps = ['de21', 'de22']
if cfg.get('init', 'map') in renpas_maps:
df = get_electrical_transmission_renpass()
else:
df = get_electrical_transmission_default()

if duplicate:
values = df.copy()

def id_inverter(name):
return '-'.join([name.split('-')[1], name.split('-')[0]])

df.index = df.index.map(id_inverter)

df = pd.DataFrame(pd.concat([values, df]))
return df


def get_electrical_transmission_default():
try:
pwr_lines = pd.DataFrame(geometries.deflex_power_lines())
except FileNotFoundError:
pwr_lines = pd.DataFrame()
def add_reverse_direction(df):
"""
Duplicate all entries of a DataFrame with a reverse index. The index must
contain a dash between two sub-strings.
"""
values = df.copy()

def id_inverter(name):
"""Swap the sub-parts of a string left and right of a dash."""
return '-'.join([name.split('-')[1], name.split('-')[0]])

df.index = df.index.map(id_inverter)

return pd.DataFrame(pd.concat([values, df]))


def get_electrical_transmission_default(rmap=None, power_lines=None,
both_directions=False):
"""
Creates a default set of transmission capacities, distance and efficiency.
The map of the lines must exist in the geometries directory. The default
values are infinity for the capacity, nan for the distance and 1 for the
efficiency.
Parameters
----------
rmap : str
The name of the transmission line map, that is part of deflex.
power_lines : iterable[str]
A list of names of transmission lines. All name must contain a dash
between the id of the regions (FromRegion-ToRegion).
both_directions : bool
If True any line will be replicated in the reverse direction.
Returns
-------
pd.DataFrame
Transmission capacity, distance and efficiency between regions
Examples
--------
>>> df = get_electrical_transmission_default('de21')
>>> df.loc['DE10-DE12', 'capacity']
inf
>>> df.loc['DE10-DE12', 'distance']
nan
>>> df.loc['DE10-DE12', 'efficiency']
1.0
>>> len(df)
39
>>> len(get_electrical_transmission_default('de22'))
40
>>> len(get_electrical_transmission_default('de17'))
31
>>> len(get_electrical_transmission_default('de02'))
1
>>> my_lines = ['reg1-reg2', 'reg2-reg3']
>>> df = get_electrical_transmission_default(power_lines=my_lines)
>>> df.loc['reg1-reg2', 'capacity']
inf
>>> df = get_electrical_transmission_default(power_lines=my_lines,
... both_directions=True)
>>> df.loc['reg2-reg1', 'capacity']
inf
"""
if power_lines is None:
power_lines = pd.DataFrame(geometries.deflex_power_lines(rmap)).index

df = pd.DataFrame()
for l in pwr_lines.index:
for l in power_lines:
df.loc[l, 'capacity'] = float('inf')
df.loc[l, 'distance'] = float('nan')
df.loc[l, 'efficiency'] = 1

if both_directions is True:
df = add_reverse_direction(df)
return df


def get_electrical_transmission_renpass():
def get_electrical_transmission_renpass(both_directions=False):
"""
Prepare the transmission capacity and distance between de21 regions from
the renpass database. The original table of the reegis database is
transferred to a csv file, which is part of the reegis package. As renpass
is deprecated it will not change in the future. The index uses the format
'region1-region2'. The distance is taken from centroid to centroid. By
default every region pair exists only once. It is possible to get an entry
in both directions if the parameter `both_directions` is set True.
The capacity calculation is taken from the description of the renpass
package [1]_. The data is taken from the renpass database [2]_.
This function is only valid for the original renpass region set.
Parameters
----------
both_directions : bool
If True any line will be replicated in the reverse direction.
Returns
-------
pd.DataFrame
Transmission capacity and distance between regions
References
----------
.. [1] Wiese, Frauke (2015). „Renewable Energy Pathways Simulation
System – Open Source as an approach to meet challenges in energy
modeling“. Diss. University of Flensburg. URL :
https://www.reiner-lemoine-stiftung.de/pdf/dissertationen/Dissertation_Frauke_Wiese.pdf.
(page 49)
.. [2] Wiese, F.: Renpass - Renewable Energy Pathways Simulation System,
https://github.com/fraukewiese/renpass
Examples
--------
>>> df = get_electrical_transmission_renpass()
>>> int(df.loc['DE11-DE17', 'capacity'])
2506
>>> int(df.loc['DE18-DE17', 'distance'])
119
>>> df.loc['DE08-DE06']
capacity 7519.040402
distance 257.000000
Name: DE08-DE06, dtype: float64
>>> df = get_electrical_transmission_renpass(both_directions=True)
>>> int(df.loc['DE11-DE17', 'capacity'])
2506
>>> int(df.loc['DE17-DE11', 'capacity'])
2506
"""
f_security = cfg.get('transmission', 'security_factor')
current_max = cfg.get('transmission', 'current_max')

grid = pd.read_csv(os.path.join(
cfg.get('paths', 'data_deflex'),
cfg.get('transmission', 'transmission_renpass')))

# renpass F.Wiese (page 49)
grid['capacity_calc'] = (grid.circuits * current_max * grid.voltage *
f_security * math.sqrt(3) / 1000)

Expand All @@ -101,22 +199,14 @@ def get_electrical_transmission_renpass():
elif cap2 == 0:
pwr_lines.loc[l, 'capacity'] = cap1
pwr_lines.loc[l, 'distance'] = dist1
elif cap1 == cap2:
pwr_lines.loc[l, 'capacity'] = cap1
pwr_lines.loc[l, 'distance'] = dist1
else:
msg = ("The same line ({0}, {1}) has different capacities: {2} "
"!= {3}")
raise ValueError(msg.format(a, b, cap1, cap2))

# plot_grid(pwr_lines)
df = pwr_lines[['capacity', 'distance']]
return df

if both_directions is True:
df = add_reverse_direction(df)

def get_grid():
return pd.read_csv(os.path.join('data', 'grid', 'de21_transmission.csv'),
index_col='Unnamed: 0')
return df


if __name__ == "__main__":
Expand Down

0 comments on commit 5148c5f

Please sign in to comment.