Passed
Pull Request — dev (#1181)
by
unknown
05:34
created

hts_to_etrago()   C

Complexity

Conditions 6

Size

Total Lines 199
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 79
dl 0
loc 199
rs 6.7539
c 0
b 0
f 0
cc 6
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""
2
The central module creating heat demand time series for the eTraGo tool
3
"""
4
from egon.data import config, db
5
from egon.data.db import next_etrago_id
6
from egon.data.datasets import Dataset
7
from egon.data.datasets.scenario_parameters import get_sector_parameters
8
9
import pandas as pd
10
import numpy as np
11
12
13
def hts_to_etrago(scenario):
14
    sources = config.datasets()["etrago_heat"]["sources"]
15
    targets = config.datasets()["etrago_heat"]["targets"]
16
    carriers = ["central_heat", "rural_heat", "rural_gas_boiler"]
17
18
    if "status" in scenario:
19
        carriers = ["central_heat", "rural_heat"]
20
21
    for carrier in carriers:
22
        if carrier == "central_heat":
23
            # Map heat buses to district heating id and area_id
24
            # interlinking bus_id and area_id
25
            bus_area = db.select_dataframe(
26
                f"""
27
                 SELECT bus_id, area_id, id FROM
28
                 {targets['heat_buses']['schema']}.
29
                 {targets['heat_buses']['table']}
30
                 JOIN {sources['district_heating_areas']['schema']}.
31
                     {sources['district_heating_areas']['table']}
32
                 ON ST_Transform(ST_Centroid(geom_polygon), 4326) = geom
33
                 WHERE carrier = '{carrier}'
34
                 AND scenario='{scenario}'
35
                 AND scn_name = '{scenario}'
36
                 """,
37
                index_col="id",
38
            )
39
40
            # district heating time series time series
41
            disct_time_series = db.select_dataframe(
42
                f"""
43
                                SELECT * FROM 
44
                                demand.egon_timeseries_district_heating
45
                                WHERE scenario ='{scenario}'                                
46
                                """
47
            )
48
            # bus_id connected to corresponding time series
49
            bus_ts = pd.merge(
50
                bus_area, disct_time_series, on="area_id", how="inner"
51
            )
52
53
        elif carrier == "rural_heat":
54
            # interlinking heat_bus_id and mv_grid bus_id
55
            bus_sub = db.select_dataframe(
56
                f"""
57
                 SELECT {targets['heat_buses']['schema']}.
58
                 {targets['heat_buses']['table']}.bus_id as heat_bus_id, 
59
                 {sources['egon_mv_grid_district']['schema']}.
60
                             {sources['egon_mv_grid_district']['table']}.bus_id as 
61
                             bus_id FROM
62
                 {targets['heat_buses']['schema']}.
63
                 {targets['heat_buses']['table']}
64
                 JOIN {sources['egon_mv_grid_district']['schema']}.
65
                             {sources['egon_mv_grid_district']['table']}
66
                 ON ST_Transform(ST_Centroid({sources['egon_mv_grid_district']['schema']}.
67
                             {sources['egon_mv_grid_district']['table']}.geom), 
68
                                 4326) = {targets['heat_buses']['schema']}.
69
                                         {targets['heat_buses']['table']}.geom
70
                 WHERE carrier = '{carrier}'
71
                 AND scn_name = '{scenario}'
72
                 """
73
            )
74
            ##**scenario name still needs to be adjusted in bus_sub**
75
76
            # individual heating time series
77
            ind_time_series = db.select_dataframe(
78
                f"""
79
                SELECT scenario, bus_id, dist_aggregated_mw FROM 
80
                demand.egon_etrago_timeseries_individual_heating
81
                WHERE scenario ='{scenario}'
82
                AND carrier = 'heat_pump'
83
                """
84
            )
85
86
            # bus_id connected to corresponding time series
87
            bus_ts = pd.merge(
88
                bus_sub, ind_time_series, on="bus_id", how="inner"
89
            )
90
91
            # Connect  heat loads to heat buses
92
            bus_ts.loc[:, "bus_id"] = bus_ts.loc[:, "heat_bus_id"]
93
94
        else:
95
            efficiency_gas_boiler = get_sector_parameters("heat", scenario)[
96
                "efficiency"
97
            ]["rural_gas_boiler"]
98
99
            # Select rural heat demand coverd by individual gas boilers
100
            ind_time_series = db.select_dataframe(
101
                f"""
102
                SELECT * FROM 
103
                demand.egon_etrago_timeseries_individual_heating
104
                WHERE scenario ='{scenario}'
105
                AND carrier = 'CH4'
106
                """
107
            )
108
109
            # Select geoetry of medium voltage grid districts
110
            mvgd_geom = db.select_geodataframe(
111
                f"""
112
                SELECT bus_id, ST_CENTROID(geom) as geom FROM 
113
                {sources['egon_mv_grid_district']['schema']}.
114
                {sources['egon_mv_grid_district']['table']}
115
                """
116
            )
117
118
            # Select geometry of gas (CH4) voronoi
119
            gas_voronoi = db.select_geodataframe(
120
                f"""
121
                SELECT bus_id, geom FROM 
122
                grid.egon_gas_voronoi
123
                WHERE scn_name = '{scenario}'
124
                AND carrier = 'CH4'
125
                """
126
            )
127
128
            # Map centroid of mvgd to gas voronoi
129
            join = mvgd_geom.sjoin(gas_voronoi, lsuffix="AC", rsuffix="gas")[
130
                ["bus_id_AC", "bus_id_gas"]
131
            ].set_index("bus_id_AC")
132
133
            # Assign gas bus to each rural heat demand coverd by gas boiler
134
            ind_time_series["gas_bus"] = join.loc[
135
                ind_time_series.bus_id
136
            ].values
137
138
            # Initialize dataframe to store final heat demand per gas node
139
            gas_ts = pd.DataFrame(
140
                index=ind_time_series["gas_bus"].unique(), columns=range(8760)
141
            )
142
143
            # Group heat demand per hour in the year
144
            for i in range(8760):
145
                gas_ts[i] = (
146
                    ind_time_series.set_index("gas_bus")
147
                    .dist_aggregated_mw.str[i]
148
                    .groupby("gas_bus")
149
                    .sum()
150
                    .div(efficiency_gas_boiler)
151
                )
152
153
            # Prepare resulting DataFrame
154
            bus_ts = pd.DataFrame(columns=["dist_aggregated_mw", "bus_id"])
155
156
            # Insert values to dataframe
157
            bus_ts.dist_aggregated_mw = gas_ts.values.tolist()
158
            bus_ts.bus_id = gas_ts.index
159
160
        # Delete existing data from database
161
        db.execute_sql(
162
            f"""
163
            DELETE FROM grid.egon_etrago_load
164
            WHERE scn_name = '{scenario}'
165
            AND carrier = '{carrier}'
166
            """
167
        )
168
169
        db.execute_sql(
170
            f"""
171
            DELETE FROM
172
            grid.egon_etrago_load_timeseries
173
            WHERE scn_name = '{scenario}'
174
            AND load_id NOT IN (
175
            SELECT load_id FROM
176
            grid.egon_etrago_load
177
            WHERE scn_name = '{scenario}')
178
            """
179
        )
180
181
        next_id = next_etrago_id("load")
182
183
        bus_ts["load_id"] = np.arange(len(bus_ts)) + next_id
184
185
        etrago_load = pd.DataFrame(index=range(len(bus_ts)))
186
        etrago_load["scn_name"] = scenario
187
        etrago_load["load_id"] = bus_ts.load_id
188
        etrago_load["bus"] = bus_ts.bus_id
189
        etrago_load["carrier"] = carrier
190
        etrago_load["sign"] = -1
191
192
        etrago_load.to_sql(
193
            "egon_etrago_load",
194
            schema="grid",
195
            con=db.engine(),
196
            if_exists="append",
197
            index=False,
198
        )
199
200
        etrago_load_timeseries = pd.DataFrame(index=range(len(bus_ts)))
201
        etrago_load_timeseries["scn_name"] = scenario
202
        etrago_load_timeseries["load_id"] = bus_ts.load_id
203
        etrago_load_timeseries["temp_id"] = 1
204
        etrago_load_timeseries["p_set"] = bus_ts.loc[:, "dist_aggregated_mw"]
205
206
        etrago_load_timeseries.to_sql(
207
            "egon_etrago_load_timeseries",
208
            schema="grid",
209
            con=db.engine(),
210
            if_exists="append",
211
            index=False,
212
        )
213
214
215
def demand():
216
    """Insert demand timeseries for heat into eTraGo tables
217
218
    Returns
219
    -------
220
    None.
221
222
    """
223
    for scenario in config.settings()["egon-data"]["--scenarios"]:
224
        hts_to_etrago(scenario)
225
226
227
class HtsEtragoTable(Dataset):
228
    """
229
    Collect heat demand time series for the eTraGo tool
230
231
    This dataset collects data for individual and district heating demands
232
    and writes that into the tables that can be read by the eTraGo tool.
233
234
    *Dependencies*
235
      * :py:class:`DistrictHeatingAreas <egon.data.datasets.district_heating_areas.DistrictHeatingAreas>`
236
      * :py:class:`HeatEtrago <egon.data.datasets.heat_etrago.HeatEtrago>`
237
      * :py:class:`MvGridDistricts <egon.data.datasets.mv_grid_districts.mv_grid_districts_setup>`
238
      * :py:class:`HeatPumps2035 <egon.data.datasets.heat_supply.individual_heating.HeatPumps2035>`
239
      * :py:class:`HeatTimeSeries <egon.data.datasets.heat_demand_timeseries.HeatTimeSeries>`
240
241
    *Resulting tables*
242
      * :py:class:`grid.egon_etrago_load <egon.data.datasets.etrago_setup.EgonPfHvLoad>` is extended
243
      * :py:class:`grid.egon_etrago_load_timeseries <egon.data.datasets.etrago_setup.EgonPfHvLoadTimeseries>` is extended
244
245
    """
246
247
    #:
248
    name: str = "HtsEtragoTable"
249
    #:
250
    version: str = "0.0.6"
251
252
    def __init__(self, dependencies):
253
        super().__init__(
254
            name=self.name,
255
            version=self.version,
256
            dependencies=dependencies,
257
            tasks=(demand,),
258
        )
259