Completed
Push — dev ( 8582b4...82307e )
by
unknown
30s queued 19s
created

data.datasets.chp_etrago.insert_egon100re()   B

Complexity

Conditions 2

Size

Total Lines 107
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 47
dl 0
loc 107
rs 8.7345
c 0
b 0
f 0
cc 2
nop 0

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 containing all code dealing with chp for eTraGo.
3
"""
4
5
import geopandas as gpd
6
import pandas as pd
7
8
from egon.data import config, db
9
from egon.data.datasets import Dataset
10
from egon.data.datasets.etrago_setup import link_geom_from_buses
11
from egon.data.datasets.scenario_parameters import get_sector_parameters
12
13
14
class ChpEtrago(Dataset):
15
    """
16
    Collect data related to combined heat and power plants for the eTraGo tool
17
18
    This dataset collects data for combined heat and power plants and puts it into a format that
19
    is needed for the transmission grid optimisation within the tool eTraGo.
20
    This data is then writting into the corresponding tables that are read by eTraGo.
21
22
23
    *Dependencies*
24
      * :py:class:`HeatEtrago <egon.data.datasets.heat_etrago.HeatEtrago>`
25
      * :py:class:`Chp <egon.data.datasets.chp.Chp>`
26
27
    *Resulting tables*
28
      * :py:class:`grid.egon_etrago_link <egon.data.datasets.etrago_setup.EgonPfHvLink>` is extended
29
      * :py:class:`grid.egon_etrago_generator <egon.data.datasets.etrago_setup.EgonPfHvGenerator>` is extended
30
31
    """
32
33
    #:
34
    name: str = "ChpEtrago"
35
    #:
36
    version: str = "0.0.6"
37
38
    def __init__(self, dependencies):
39
        super().__init__(
40
            name=self.name,
41
            version=self.version,
42
            dependencies=dependencies,
43
            tasks=(insert),
44
        )
45
46
47
def insert_egon100re():
48
    sources = config.datasets()["chp_etrago"]["sources"]
49
50
    targets = config.datasets()["chp_etrago"]["targets"]
51
52
    db.execute_sql(
53
        f"""
54
        DELETE FROM {targets['link']['schema']}.{targets['link']['table']}
55
        WHERE carrier LIKE '%%CHP%%'
56
        AND scn_name = 'eGon100RE'
57
        AND bus0 IN
58
        (SELECT bus_id
59
         FROM {sources['etrago_buses']['schema']}.{sources['etrago_buses']['table']}
60
         WHERE scn_name = 'eGon100RE'
61
         AND country = 'DE')
62
        AND bus1 IN
63
        (SELECT bus_id
64
         FROM {sources['etrago_buses']['schema']}.{sources['etrago_buses']['table']}
65
         WHERE scn_name = 'eGon100RE'
66
         AND country = 'DE')
67
        """
68
    )
69
70
    # Select all CHP plants used in district heating
71
    chp_dh = db.select_dataframe(
72
        f"""
73
        SELECT electrical_bus_id, ch4_bus_id, a.carrier,
74
        SUM(el_capacity) AS el_capacity, SUM(th_capacity) AS th_capacity,
75
        c.bus_id as heat_bus_id
76
        FROM {sources['chp_table']['schema']}.
77
        {sources['chp_table']['table']} a
78
        JOIN {sources['district_heating_areas']['schema']}.
79
        {sources['district_heating_areas']['table']}  b
80
        ON a.district_heating_area_id = b.area_id
81
        JOIN grid.egon_etrago_bus c
82
        ON ST_Transform(ST_Centroid(b.geom_polygon), 4326) = c.geom
83
84
        WHERE a.scenario='eGon100RE'
85
        AND b.scenario = 'eGon100RE'
86
        AND c.scn_name = 'eGon100RE'
87
        AND c.carrier = 'central_heat'
88
        AND NOT district_heating_area_id IS NULL
89
        GROUP BY (
90
            electrical_bus_id, ch4_bus_id, a.carrier, c.bus_id)
91
        """
92
    )
93
94
    if chp_dh.empty:
95
        print("No CHP for district heating in scenario eGon100RE")
96
        return
97
98
    # Create geodataframes for gas CHP plants
99
    chp_el = link_geom_from_buses(
100
        gpd.GeoDataFrame(
101
            index=chp_dh.index,
102
            data={
103
                "scn_name": "eGon2035",
104
                "bus0": chp_dh.loc[:, "ch4_bus_id"].astype(int),
105
                "bus1": chp_dh.loc[:, "electrical_bus_id"].astype(int),
106
                "p_nom": chp_dh.loc[:, "el_capacity"],
107
                "carrier": "central_gas_CHP",
108
            },
109
        ),
110
        "eGon100RE",
111
    )
112
    # Set index
113
    chp_el["link_id"] = range(
114
        db.next_etrago_id("link"), len(chp_el) + db.next_etrago_id("link")
115
    )
116
117
    # Add marginal cost which is only VOM in case of gas chp
118
    chp_el["marginal_cost"] = get_sector_parameters("gas", "eGon100RE")[
119
        "marginal_cost"
120
    ]["chp_gas"]
121
122
    # Insert into database
123
    chp_el.to_postgis(
124
        targets["link"]["table"],
125
        schema=targets["link"]["schema"],
126
        con=db.engine(),
127
        if_exists="append",
128
    )
129
130
    #
131
    chp_heat = link_geom_from_buses(
132
        gpd.GeoDataFrame(
133
            index=chp_dh.index,
134
            data={
135
                "scn_name": "eGon100RE",
136
                "bus0": chp_dh.loc[:, "ch4_bus_id"].astype(int),
137
                "bus1": chp_dh.loc[:, "heat_bus_id"].astype(int),
138
                "p_nom": chp_dh.loc[:, "th_capacity"],
139
                "carrier": "central_gas_CHP_heat",
140
            },
141
        ),
142
        "eGon100RE",
143
    )
144
145
    chp_heat["link_id"] = range(
146
        db.next_etrago_id("link"), len(chp_heat) + db.next_etrago_id("link")
147
    )
148
149
    chp_heat.to_postgis(
150
        targets["link"]["table"],
151
        schema=targets["link"]["schema"],
152
        con=db.engine(),
153
        if_exists="append",
154
    )
155
156
157
def insert_scenario(scenario):
158
    sources = config.datasets()["chp_etrago"]["sources"]
159
160
    targets = config.datasets()["chp_etrago"]["targets"]
161
162
    db.execute_sql(
163
        f"""
164
        DELETE FROM {targets['link']['schema']}.{targets['link']['table']}
165
        WHERE carrier LIKE '%%CHP%%'
166
        AND scn_name = '{scenario}'
167
        AND bus0 IN
168
        (SELECT bus_id
169
         FROM {sources['etrago_buses']['schema']}.{sources['etrago_buses']['table']}
170
         WHERE scn_name = '{scenario}'
171
         AND country = 'DE')
172
        AND bus1 IN
173
        (SELECT bus_id
174
         FROM {sources['etrago_buses']['schema']}.{sources['etrago_buses']['table']}
175
         WHERE scn_name = '{scenario}'
176
         AND country = 'DE')
177
        """
178
    )
179
    db.execute_sql(
180
        f"""
181
        DELETE FROM {targets['generator']['schema']}.{targets['generator']['table']}
182
        WHERE carrier LIKE '%%CHP%%'
183
        AND scn_name = '{scenario}'
184
        """
185
    )
186
    # Select all CHP plants used in district heating
187
    chp_dh = db.select_dataframe(
188
        f"""
189
        SELECT electrical_bus_id, ch4_bus_id, a.carrier,
190
        SUM(el_capacity) AS el_capacity, SUM(th_capacity) AS th_capacity,
191
        c.bus_id as heat_bus_id
192
        FROM {sources['chp_table']['schema']}.
193
        {sources['chp_table']['table']} a
194
        JOIN {sources['district_heating_areas']['schema']}.
195
        {sources['district_heating_areas']['table']}  b
196
        ON a.district_heating_area_id = b.area_id
197
        JOIN grid.egon_etrago_bus c
198
        ON ST_Transform(ST_Centroid(b.geom_polygon), 4326) = c.geom
199
200
        WHERE a.scenario='{scenario}'
201
        AND b.scenario = '{scenario}'
202
        AND c.scn_name = '{scenario}'
203
        AND c.carrier = 'central_heat'
204
        AND NOT district_heating_area_id IS NULL
205
        GROUP BY (
206
            electrical_bus_id, ch4_bus_id, a.carrier, c.bus_id)
207
        """
208
    )
209
    # Divide into biomass and gas CHP which are modelled differently
210
    chp_link_dh = chp_dh[chp_dh.carrier == "gas"].index
211
    chp_generator_dh = chp_dh[chp_dh.carrier != "gas"].index
212
213
    # Create geodataframes for gas CHP plants
214
    chp_el = link_geom_from_buses(
215
        gpd.GeoDataFrame(
216
            index=chp_link_dh,
217
            data={
218
                "scn_name": scenario,
219
                "bus0": chp_dh.loc[chp_link_dh, "ch4_bus_id"].astype(int),
220
                "bus1": chp_dh.loc[chp_link_dh, "electrical_bus_id"].astype(
221
                    int
222
                ),
223
                "p_nom": chp_dh.loc[chp_link_dh, "el_capacity"],
224
                "carrier": "central_gas_CHP",
225
            },
226
        ),
227
        scenario,
228
    )
229
    # Set index
230
    chp_el["link_id"] = range(
231
        db.next_etrago_id("link"), len(chp_el) + db.next_etrago_id("link")
232
    )
233
234
    # Add marginal cost which is only VOM in case of gas chp
235
    chp_el["marginal_cost"] = get_sector_parameters("gas", scenario)[
236
        "marginal_cost"
237
    ]["chp_gas"]
238
239
    # Insert into database
240
    chp_el.to_postgis(
241
        targets["link"]["table"],
242
        schema=targets["link"]["schema"],
243
        con=db.engine(),
244
        if_exists="append",
245
    )
246
247
    #
248
    chp_heat = link_geom_from_buses(
249
        gpd.GeoDataFrame(
250
            index=chp_link_dh,
251
            data={
252
                "scn_name": scenario,
253
                "bus0": chp_dh.loc[chp_link_dh, "ch4_bus_id"].astype(int),
254
                "bus1": chp_dh.loc[chp_link_dh, "heat_bus_id"].astype(int),
255
                "p_nom": chp_dh.loc[chp_link_dh, "th_capacity"],
256
                "carrier": "central_gas_CHP_heat",
257
            },
258
        ),
259
        scenario,
260
    )
261
262
    chp_heat["link_id"] = range(
263
        db.next_etrago_id("link"), len(chp_heat) + db.next_etrago_id("link")
264
    )
265
266
    chp_heat.to_postgis(
267
        targets["link"]["table"],
268
        schema=targets["link"]["schema"],
269
        con=db.engine(),
270
        if_exists="append",
271
    )
272
273
    # Insert biomass, coal, oil and other CHP as generators
274
    # Create geodataframes for CHP plants
275
    chp_el_gen = pd.DataFrame(
276
        index=chp_generator_dh,
277
        data={
278
            "scn_name": scenario,
279
            "bus": chp_dh.loc[chp_generator_dh, "electrical_bus_id"].astype(
280
                int
281
            ),
282
            "p_nom": chp_dh.loc[chp_generator_dh, "el_capacity"],
283
            "carrier": chp_dh.loc[chp_generator_dh, "carrier"],
284
        },
285
    )
286
287
    chp_el_gen["generator_id"] = range(
288
        db.next_etrago_id("generator"),
289
        len(chp_el_gen) + db.next_etrago_id("generator"),
290
    )
291
292
    # Add marginal cost
293
    chp_el_gen["marginal_cost"] = (
294
        pd.Series(
295
            get_sector_parameters("electricity", scenario)["marginal_cost"]
296
        )
297
        .rename({"other_non_renewable": "others"})
298
        .loc[chp_el_gen["carrier"]]
299
    ).values
300
301
    chp_el_gen["carrier"] = (
302
        "central_" + chp_dh.loc[chp_generator_dh, "carrier"] + "_CHP"
303
    )
304
305
    chp_el_gen.to_sql(
306
        targets["generator"]["table"],
307
        schema=targets["generator"]["schema"],
308
        con=db.engine(),
309
        if_exists="append",
310
        index=False,
311
    )
312
313
    chp_heat_gen = pd.DataFrame(
314
        index=chp_generator_dh,
315
        data={
316
            "scn_name": scenario,
317
            "bus": chp_dh.loc[chp_generator_dh, "heat_bus_id"].astype(int),
318
            "p_nom": chp_dh.loc[chp_generator_dh, "th_capacity"],
319
            "carrier": "central_"
320
            + chp_dh.loc[chp_generator_dh, "carrier"]
321
            + "_CHP_heat",
322
        },
323
    )
324
325
    chp_heat_gen["generator_id"] = range(
326
        db.next_etrago_id("generator"),
327
        len(chp_heat_gen) + db.next_etrago_id("generator"),
328
    )
329
330
    chp_heat_gen.to_sql(
331
        targets["generator"]["table"],
332
        schema=targets["generator"]["schema"],
333
        con=db.engine(),
334
        if_exists="append",
335
        index=False,
336
    )
337
338
    chp_industry = db.select_dataframe(
339
        f"""
340
        SELECT electrical_bus_id, ch4_bus_id, carrier,
341
        SUM(el_capacity) AS el_capacity, SUM(th_capacity) AS th_capacity
342
        FROM {sources['chp_table']['schema']}.{sources['chp_table']['table']}
343
        WHERE scenario='{scenario}'
344
        AND district_heating_area_id IS NULL
345
        GROUP BY (electrical_bus_id, ch4_bus_id, carrier)
346
        """
347
    )
348
    chp_link_ind = chp_industry[chp_industry.carrier == "gas"].index
349
350
    chp_generator_ind = chp_industry[chp_industry.carrier != "gas"].index
351
352
    chp_el_ind = link_geom_from_buses(
353
        gpd.GeoDataFrame(
354
            index=chp_link_ind,
355
            data={
356
                "scn_name": scenario,
357
                "bus0": chp_industry.loc[chp_link_ind, "ch4_bus_id"].astype(
358
                    int
359
                ),
360
                "bus1": chp_industry.loc[
361
                    chp_link_ind, "electrical_bus_id"
362
                ].astype(int),
363
                "p_nom": chp_industry.loc[chp_link_ind, "el_capacity"],
364
                "carrier": "industrial_gas_CHP",
365
            },
366
        ),
367
        scenario,
368
    )
369
370
    chp_el_ind["link_id"] = range(
371
        db.next_etrago_id("link"), len(chp_el_ind) + db.next_etrago_id("link")
372
    )
373
374
    # Add marginal cost which is only VOM in case of gas chp
375
    chp_el_ind["marginal_cost"] = get_sector_parameters("gas", scenario)[
376
        "marginal_cost"
377
    ]["chp_gas"]
378
379
    chp_el_ind.to_postgis(
380
        targets["link"]["table"],
381
        schema=targets["link"]["schema"],
382
        con=db.engine(),
383
        if_exists="append",
384
    )
385
386
    # Insert biomass CHP as generators
387
    chp_el_ind_gen = pd.DataFrame(
388
        index=chp_generator_ind,
389
        data={
390
            "scn_name": scenario,
391
            "bus": chp_industry.loc[
392
                chp_generator_ind, "electrical_bus_id"
393
            ].astype(int),
394
            "p_nom": chp_industry.loc[chp_generator_ind, "el_capacity"],
395
            "carrier": chp_industry.loc[chp_generator_ind, "carrier"],
396
        },
397
    )
398
399
    chp_el_ind_gen["generator_id"] = range(
400
        db.next_etrago_id("generator"),
401
        len(chp_el_ind_gen) + db.next_etrago_id("generator"),
402
    )
403
404
    # Add marginal cost
405
    chp_el_ind_gen["marginal_cost"] = (
406
        pd.Series(
407
            get_sector_parameters("electricity", scenario)["marginal_cost"]
408
        )
409
        .rename({"other_non_renewable": "others"})
410
        .loc[chp_el_ind_gen["carrier"]]
411
    ).values
412
413
    # Update carrier
414
    chp_el_ind_gen["carrier"] = "industrial_" + chp_el_ind_gen.carrier + "_CHP"
415
416
    chp_el_ind_gen.to_sql(
417
        targets["generator"]["table"],
418
        schema=targets["generator"]["schema"],
419
        con=db.engine(),
420
        if_exists="append",
421
        index=False,
422
    )
423
424
425
def insert():
426
    """Insert combined heat and power plants into eTraGo tables.
427
428
    Gas CHP plants are modeled as links to the gas grid,
429
    biomass CHP plants (only in eGon2035) are modeled as generators
430
431
    Returns
432
    -------
433
    None.
434
435
    """
436
437
    for scenario in config.settings()["egon-data"]["--scenarios"]:
438
        if scenario != "eGon100RE":
439
            insert_scenario(scenario)
440
441
        else:
442
            insert_egon100re()
443