Passed
Pull Request — dev (#931)
by
unknown
01:49
created

get_foreign_gas_bus_id()   A

Complexity

Conditions 2

Size

Total Lines 54
Code Lines 23

Duplication

Lines 54
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 23
dl 54
loc 54
rs 9.328
c 0
b 0
f 0
cc 2
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
"""Central module containing code dealing with gas neighbours for eGon2035
2
"""
3
4
from pathlib import Path
5
from urllib.request import urlretrieve
6
import ast
7
import zipfile
8
9
from shapely.geometry import LineString, MultiLineString
10
import geopandas as gpd
11
import pandas as pd
12
import pypsa
13
14
from egon.data import config, db
15
from egon.data.datasets.electrical_neighbours import (
16
    get_foreign_bus_id,
17
    get_map_buses,
18
)
19
from egon.data.datasets.gas_neighbours.gas_abroad import (
20
    get_foreign_gas_bus_id,
21
    insert_gas_grid_capacities,
22
    insert_generators,
23
)
24
from egon.data.datasets.scenario_parameters import get_sector_parameters
25
26
countries = [
27
    "AT",
28
    "BE",
29
    "CH",
30
    "CZ",
31
    "DK",
32
    "FR",
33
    "GB",
34
    "LU",
35
    "NL",
36
    "NO",
37
    "PL",
38
    "RU",
39
    "SE",
40
    "UK",
41
]
42
43
44
def read_LNG_capacities():
45
    """Read LNG import capacities from Scigrid gas data
46
47
    Returns
48
    -------
49
    IGGIELGN_LNGs: pandas.Series
50
        LNG terminal capacities per foreign country node (in GWh/d)
51
52
    """
53
    lng_file = "datasets/gas_data/data/IGGIELGN_LNGs.csv"
54
    IGGIELGN_LNGs = gpd.read_file(lng_file)
55
56
    map_countries_scigrid = {
57
        "BE": "BE00",
58
        "EE": "EE00",
59
        "EL": "GR00",
60
        "ES": "ES00",
61
        "FI": "FI00",
62
        "FR": "FR00",
63
        "GB": "UK00",
64
        "IT": "ITCN",
65
        "LT": "LT00",
66
        "LV": "LV00",
67
        "MT": "MT00",
68
        "NL": "NL00",
69
        "PL": "PL00",
70
        "PT": "PT00",
71
        "SE": "SE01",
72
    }
73
74
    conversion_factor = 437.5  # MCM/day to MWh/h
75
    c2 = 24 / 1000  # MWh/h to GWh/d
76
    p_nom = []
77
78
    for index, row in IGGIELGN_LNGs.iterrows():
79
        param = ast.literal_eval(row["param"])
80
        p_nom.append(
81
            param["max_cap_store2pipe_M_m3_per_d"] * conversion_factor * c2
82
        )
83
84
    IGGIELGN_LNGs["LNG max_cap_store2pipe_M_m3_per_d (in GWh/d)"] = p_nom
85
86
    IGGIELGN_LNGs.drop(
87
        [
88
            "uncertainty",
89
            "method",
90
            "param",
91
            "comment",
92
            "tags",
93
            "source_id",
94
            "lat",
95
            "long",
96
            "geometry",
97
            "id",
98
            "name",
99
            "node_id",
100
        ],
101
        axis=1,
102
        inplace=True,
103
    )
104
105
    IGGIELGN_LNGs["Country"] = IGGIELGN_LNGs["country_code"].map(
106
        map_countries_scigrid
107
    )
108
    IGGIELGN_LNGs = (
109
        IGGIELGN_LNGs.groupby(["Country"])[
110
            "LNG max_cap_store2pipe_M_m3_per_d (in GWh/d)"
111
        ]
112
        .sum()
113
        .sort_index()
114
    )
115
116
    return IGGIELGN_LNGs
117
118
119
def calc_capacities():
120
    """Calculates gas production capacities of neighbouring countries
121
122
    For each neigbouring country, this function calculates the gas
123
    generation capacity in 2035 using the function
124
    :py:func:`calc_capacity_per_year` for 2030 and 2040 and
125
    interpolating the results. These capacities include LNG import, as
126
    well as conventional and biogas production.
127
    Two conventional gas generators for are added for Norway and Russia
128
    interpolating the supply potential (min) values from the TYNPD 2020
129
    for 2030 and 2040.
130
131
    Returns
132
    -------
133
    grouped_capacities: pandas.DataFrame
134
        Gas production capacities per foreign node
135
136
    """
137
138
    sources = config.datasets()["gas_neighbours"]["sources"]
139
140
    # insert installed capacities
141
    file = zipfile.ZipFile(f"tyndp/{sources['tyndp_capacities']}")
142
    df0 = pd.read_excel(
143
        file.open("TYNDP-2020-Scenario-Datafile.xlsx").read(),
144
        sheet_name="Gas Data",
145
    )
146
147
    df = (
148
        df0.query(
149
            'Scenario == "Distributed Energy" &'
150
            ' (Case == "Peak" | Case == "Average") &'
151
            # Case: 2 Week/Average/DF/Peak
152
            ' Category == "Production"'
153
        )
154
        .drop(
155
            columns=[
156
                "Generator_ID",
157
                "Climate Year",
158
                "Simulation_ID",
159
                "Node 1",
160
                "Path",
161
                "Direct/Indirect",
162
                "Sector",
163
                "Note",
164
                "Category",
165
                "Scenario",
166
            ]
167
        )
168
        .set_index("Node/Line")
169
        .sort_index()
170
    )
171
172
    lng = read_LNG_capacities()
173
    df_2030 = calc_capacity_per_year(df, lng, 2030)
174
    df_2040 = calc_capacity_per_year(df, lng, 2040)
175
176
    # Conversion GWh/d to MWh/h
177
    conversion_factor = 1000 / 24
178
179
    df_2035 = pd.concat([df_2040, df_2030], axis=1)
180
    df_2035 = df_2035.drop(
181
        columns=[
182
            "Value_conv_2040",
183
            "Value_conv_2030",
184
            "Value_bio_2040",
185
            "Value_bio_2030",
186
        ]
187
    )
188
    df_2035["cap_2035"] = (df_2035["CH4_2030"] + df_2035["CH4_2040"]) / 2
189
    df_2035["e_nom_max"] = (
190
        ((df_2035["e_nom_max_2030"] + df_2035["e_nom_max_2040"]) / 2)
191
        * conversion_factor
192
        * 8760
193
    )
194
    df_2035["share_LNG_2035"] = (
195
        df_2035["share_LNG_2030"] + df_2035["share_LNG_2040"]
196
    ) / 2
197
    df_2035["share_conv_pipe_2035"] = (
198
        df_2035["share_conv_pipe_2030"] + df_2035["share_conv_pipe_2040"]
199
    ) / 2
200
    df_2035["share_bio_2035"] = (
201
        df_2035["share_bio_2030"] + df_2035["share_bio_2040"]
202
    ) / 2
203
204
    grouped_capacities = df_2035.drop(
205
        columns=[
206
            "share_LNG_2030",
207
            "share_LNG_2040",
208
            "share_conv_pipe_2030",
209
            "share_conv_pipe_2040",
210
            "share_bio_2030",
211
            "share_bio_2040",
212
            "CH4_2040",
213
            "CH4_2030",
214
            "e_nom_max_2030",
215
            "e_nom_max_2040",
216
        ]
217
    ).reset_index()
218
219
    grouped_capacities["cap_2035"] = (
220
        grouped_capacities["cap_2035"] * conversion_factor
221
    )
222
223
    # Add generators in Norway and Russia
224
    df_conv = (
225
        df0.query('Case == "Min" & Category == "Supply Potential"')
226
        .drop(
227
            columns=[
228
                "Generator_ID",
229
                "Climate Year",
230
                "Simulation_ID",
231
                "Node 1",
232
                "Path",
233
                "Direct/Indirect",
234
                "Sector",
235
                "Note",
236
                "Category",
237
                "Scenario",
238
                "Parameter",
239
                "Case",
240
            ]
241
        )
242
        .set_index("Node/Line")
243
        .sort_index()
244
    )
245
246
    df_conv_2030 = df_conv[df_conv["Year"] == 2030].rename(
247
        columns={"Value": "Value_2030"}
248
    )
249
    df_conv_2040 = df_conv[df_conv["Year"] == 2040].rename(
250
        columns={"Value": "Value_2040"}
251
    )
252
    df_conv_2035 = pd.concat([df_conv_2040, df_conv_2030], axis=1)
253
254
    df_conv_2035["cap_2035"] = (
255
        (df_conv_2035["Value_2030"] + df_conv_2035["Value_2040"]) / 2
256
    ) * conversion_factor
257
    df_conv_2035["e_nom_max"] = df_conv_2035["cap_2035"] * 8760
258
    df_conv_2035["share_LNG_2035"] = 0
259
    df_conv_2035["share_conv_pipe_2035"] = 1
260
    df_conv_2035["share_bio_2035"] = 0
261
262
    df_conv_2035 = df_conv_2035.drop(
263
        columns=[
264
            "Year",
265
            "Value_2030",
266
            "Value_2040",
267
        ]
268
    ).reset_index()
269
    df_conv_2035 = df_conv_2035.rename(columns={"Node/Line": "index"})
270
    grouped_capacities = grouped_capacities.append(df_conv_2035)
271
272
    # choose capacities for considered countries
273
    grouped_capacities = grouped_capacities[
274
        grouped_capacities["index"].str[:2].isin(countries)
275
    ]
276
    return grouped_capacities
277
278
279
def calc_capacity_per_year(df, lng, year):
280
    """Calculates gas production capacities for a specified year
281
282
    For a specified year and for the foreign country nodes this function
283
    calculates the gas production capacity, considering the gas
284
    (conventional and bio) production capacity from TYNDP data and the
285
    LGN import capacity from Scigrid gas data.
286
287
    The columns of the returned dataframe are the following:
288
      * Value_bio_year: biogas capacity prodution (in GWh/d)
289
      * Value_conv_year: conventional gas capacity prodution including
290
        LNG imports (in GWh/d)
291
      * CH4_year: total gas production capacity (in GWh/d). This value
292
        is calculated using the peak production value from the TYNDP.
293
      * e_nom_max_year: total gas production capacity representative
294
        for the whole year (in GWh/d). This value is calculated using
295
        the average production value from the TYNDP and will then be
296
        used to limit the energy that can be generated in one year.
297
      * share_LNG_year: share of LGN import capacity in the total gas
298
        production capacity
299
      * share_conv_pipe_year: share of conventional gas extraction
300
        capacity in the total gas production capacity
301
      * share_bio_year: share of biogas production capacity in the
302
        total gas production capacity
303
304
    Parameters
305
    ----------
306
    df : pandas.DataFrame
307
        Gas (conventional and bio) production capacities from TYNDP (in GWh/d)
308
309
    lng : pandas.Series
310
        LNG terminal capacities per foreign country node (in GWh/d)
311
312
    year : int
313
        Year to calculate gas production capacity for.
314
315
    Returns
316
    -------
317
    df_year : pandas.DataFrame
318
        Gas production capacities (in GWh/d) per foreign country node
319
320
    """
321
    df_conv_peak = (
322
        df[
323
            (df["Parameter"] == "Conventional")
324
            & (df["Year"] == year)
325
            & (df["Case"] == "Peak")
326
        ]
327
        .rename(columns={"Value": f"Value_conv_{year}_peak"})
328
        .drop(columns=["Parameter", "Year", "Case"])
329
    )
330
    df_conv_average = (
331
        df[
332
            (df["Parameter"] == "Conventional")
333
            & (df["Year"] == year)
334
            & (df["Case"] == "Average")
335
        ]
336
        .rename(columns={"Value": f"Value_conv_{year}_average"})
337
        .drop(columns=["Parameter", "Year", "Case"])
338
    )
339
    df_bioch4 = (
340
        df[
341
            (df["Parameter"] == "Biomethane")
342
            & (df["Year"] == year)
343
            & (df["Case"] == "Peak")
344
            # Peak and Average have the same values for biogas
345
            # production in 2030 and 2040
346
        ]
347
        .rename(columns={"Value": f"Value_bio_{year}"})
348
        .drop(columns=["Parameter", "Year", "Case"])
349
    )
350
351
    # Some values are duplicated (DE00 in 2030)
352
    df_conv_peak = df_conv_peak[~df_conv_peak.index.duplicated(keep="first")]
353
    df_conv_average = df_conv_average[
354
        ~df_conv_average.index.duplicated(keep="first")
355
    ]
356
357
    df_year = pd.concat(
358
        [df_conv_peak, df_conv_average, df_bioch4, lng], axis=1
359
    ).fillna(0)
360
    df_year = df_year[
361
        ~(
362
            (df_year[f"Value_conv_{year}_peak"] == 0)
363
            & (df_year[f"Value_bio_{year}"] == 0)
364
            & (df_year["LNG max_cap_store2pipe_M_m3_per_d (in GWh/d)"] == 0)
365
        )
366
    ]
367
    df_year[f"Value_conv_{year}"] = (
368
        df_year[f"Value_conv_{year}_peak"]
369
        + df_year["LNG max_cap_store2pipe_M_m3_per_d (in GWh/d)"]
370
    )
371
    df_year[f"CH4_{year}"] = (
372
        df_year[f"Value_conv_{year}"] + df_year[f"Value_bio_{year}"]
373
    )
374
    df_year[f"e_nom_max_{year}"] = (
375
        df_year[f"Value_conv_{year}_average"]
376
        + df_year[f"Value_bio_{year}"]
377
        + df_year["LNG max_cap_store2pipe_M_m3_per_d (in GWh/d)"]
378
    )
379
    df_year[f"share_LNG_{year}"] = (
380
        df_year["LNG max_cap_store2pipe_M_m3_per_d (in GWh/d)"]
381
        / df_year[f"e_nom_max_{year}"]
382
    )
383
    df_year[f"share_conv_pipe_{year}"] = (
384
        df_year[f"Value_conv_{year}_average"] / df_year[f"e_nom_max_{year}"]
385
    )
386
    df_year[f"share_bio_{year}"] = (
387
        df_year[f"Value_bio_{year}"] / df_year[f"e_nom_max_{year}"]
388
    )
389
390
    df_year = df_year.drop(
391
        columns=[
392
            "LNG max_cap_store2pipe_M_m3_per_d (in GWh/d)",
393
            f"Value_conv_{year}_average",
394
            f"Value_conv_{year}_peak",
395
        ]
396
    )
397
398
    return df_year
399
400
401
def calc_global_ch4_demand(Norway_global_demand_1y):
402
    """Calculates global CH4 demands abroad for eGon2035 scenario
403
404
    The data comes from TYNDP 2020 according to NEP 2021 from the
405
    scenario 'Distributed Energy', linear interpolate between 2030
406
    and 2040.
407
408
    Returns
409
    -------
410
    pandas.DataFrame
411
        Global (yearly) CH4 final demand per foreign node
412
413
    """
414
415
    sources = config.datasets()["gas_neighbours"]["sources"]
416
417
    file = zipfile.ZipFile(f"tyndp/{sources['tyndp_capacities']}")
418
    df = pd.read_excel(
419
        file.open("TYNDP-2020-Scenario-Datafile.xlsx").read(),
420
        sheet_name="Gas Data",
421
    )
422
423
    df = (
424
        df.query(
425
            'Scenario == "Distributed Energy" & '
426
            'Case == "Average" &'
427
            'Category == "Demand"'
428
        )
429
        .drop(
430
            columns=[
431
                "Generator_ID",
432
                "Climate Year",
433
                "Simulation_ID",
434
                "Node 1",
435
                "Path",
436
                "Direct/Indirect",
437
                "Sector",
438
                "Note",
439
                "Category",
440
                "Case",
441
                "Scenario",
442
            ]
443
        )
444
        .set_index("Node/Line")
445
    )
446
447
    df_2030 = (
448
        df[(df["Parameter"] == "Final demand") & (df["Year"] == 2030)]
449
        .rename(columns={"Value": "Value_2030"})
450
        .drop(columns=["Parameter", "Year"])
451
    )
452
453
    df_2040 = (
454
        df[(df["Parameter"] == "Final demand") & (df["Year"] == 2040)]
455
        .rename(columns={"Value": "Value_2040"})
456
        .drop(columns=["Parameter", "Year"])
457
    )
458
459
    # Conversion GWh/d to MWh/h
460
    conversion_factor = 1000 / 24
461
462
    df_2035 = pd.concat([df_2040, df_2030], axis=1)
463
    df_2035["GlobD_2035"] = (
464
        (df_2035["Value_2030"] + df_2035["Value_2040"]) / 2
465
    ) * conversion_factor
466
    df_2035.loc["NOS0"] = [
467
        0,
468
        0,
469
        Norway_global_demand_1y / 8760,
470
    ]  # Manually add Norway demand
471
    grouped_demands = df_2035.drop(
472
        columns=["Value_2030", "Value_2040"]
473
    ).reset_index()
474
475
    # choose demands for considered countries
476
    return grouped_demands[
477
        grouped_demands["Node/Line"].str[:2].isin(countries)
478
    ]
479
480
481
def import_ch4_demandTS():
482
    """Calculate global CH4 demand in Norway and CH4 demand profile
483
484
    Import from the PyPSA-eur-sec run the timeseries of residential
485
    rural heat per neighbor country. This timeserie is used to
486
    calculate:
487
      * the global (yearly) heat demand of Norway
488
        (that will be supplied by CH4)
489
      * the normalized CH4 hourly resolved demand profile
490
491
    Parameters
492
    ----------
493
    None.
494
495
    Returns
496
    -------
497
    Norway_global_demand: Float
498
        Yearly heat demand of Norway in MWh
499
    neighbor_loads_t: pandas.DataFrame
500
        Normalized CH4 hourly resolved demand profiles per neighbor country
501
502
    """
503
504
    cwd = Path(".")
505
    target_file = (
506
        cwd
507
        / "data_bundle_egon_data"
508
        / "pypsa_eur_sec"
509
        / "2022-07-26-egondata-integration"
510
        / "postnetworks"
511
        / "elec_s_37_lv2.0__Co2L0-1H-T-H-B-I-dist1_2050.nc"
512
    )
513
514
    network = pypsa.Network(str(target_file))
515
516
    # Set country tag for all buses
517
    network.buses.country = network.buses.index.str[:2]
518
    neighbors = network.buses[network.buses.country != "DE"]
519
    neighbors = neighbors[
520
        (neighbors["country"].isin(countries))
521
        & (neighbors["carrier"] == "residential rural heat")
522
    ].drop_duplicates(subset="country")
523
524
    neighbor_loads = network.loads[network.loads.bus.isin(neighbors.index)]
525
    neighbor_loads_t_index = neighbor_loads.index[
526
        neighbor_loads.index.isin(network.loads_t.p_set.columns)
527
    ]
528
    neighbor_loads_t = network.loads_t["p_set"][neighbor_loads_t_index]
529
    Norway_global_demand = neighbor_loads_t[
530
        "NO3 0 residential rural heat"
531
    ].sum()
532
533
    for i in neighbor_loads_t.columns:
534
        neighbor_loads_t[i] = neighbor_loads_t[i] / neighbor_loads_t[i].sum()
535
536
    return Norway_global_demand, neighbor_loads_t
537
538
539
def insert_ch4_demand(global_demand, normalized_ch4_demandTS):
540
    """Insert CH4 demands abroad in the database for eGon2035
541
542
    Parameters
543
    ----------
544
    global_demand : pandas.DataFrame
545
        Global CH4 demand per foreign node in 1 year
546
    gas_demandTS : pandas.DataFrame
547
        Normalized time serie of the demand per foreign country
548
549
    Returns
550
    -------
551
    None.
552
553
    """
554
    sources = config.datasets()["gas_neighbours"]["sources"]
555
    targets = config.datasets()["gas_neighbours"]["targets"]
556
    map_buses = get_map_buses()
557
558
    scn_name = "eGon2035"
559
    carrier = "CH4"
560
561
    # Delete existing data
562
    db.execute_sql(
563
        f"""
564
        DELETE FROM
565
        {targets['load_timeseries']['schema']}.{targets['load_timeseries']['table']}
566
        WHERE "load_id" IN (
567
            SELECT load_id FROM
568
            {targets['loads']['schema']}.{targets['loads']['table']}
569
            WHERE bus IN (
570
                SELECT bus_id FROM
571
                {sources['buses']['schema']}.{sources['buses']['table']}
572
                WHERE country != 'DE'
573
                AND scn_name = '{scn_name}')
574
            AND scn_name = '{scn_name}'
575
            AND carrier = '{carrier}'
576
        );
577
        """
578
    )
579
580
    db.execute_sql(
581
        f"""
582
        DELETE FROM
583
        {targets['loads']['schema']}.{targets['loads']['table']}
584
        WHERE bus IN (
585
            SELECT bus_id FROM
586
            {sources['buses']['schema']}.{sources['buses']['table']}
587
            WHERE country != 'DE'
588
            AND scn_name = '{scn_name}')
589
        AND scn_name = '{scn_name}'
590
        AND carrier = '{carrier}'
591
        """
592
    )
593
594
    # Set bus_id
595
    global_demand.loc[
596
        global_demand[global_demand["Node/Line"].isin(map_buses.keys())].index,
597
        "Node/Line",
598
    ] = global_demand.loc[
599
        global_demand[global_demand["Node/Line"].isin(map_buses.keys())].index,
600
        "Node/Line",
601
    ].map(
602
        map_buses
603
    )
604
    global_demand.loc[:, "bus"] = (
605
        get_foreign_gas_bus_id().loc[global_demand.loc[:, "Node/Line"]].values
606
    )
607
608
    # Add missing columns
609
    c = {"scn_name": scn_name, "carrier": carrier}
610
    global_demand = global_demand.assign(**c)
611
612
    new_id = db.next_etrago_id("load")
613
    global_demand["load_id"] = range(new_id, new_id + len(global_demand))
614
615
    ch4_demand_TS = global_demand.copy()
616
    # Remove useless columns
617
    global_demand = global_demand.drop(columns=["Node/Line", "GlobD_2035"])
618
619
    # Insert data to db
620
    global_demand.to_sql(
621
        targets["loads"]["table"],
622
        db.engine(),
623
        schema=targets["loads"]["schema"],
624
        index=False,
625
        if_exists="append",
626
    )
627
628
    # Insert time series
629
    ch4_demand_TS["Node/Line"] = ch4_demand_TS["Node/Line"].replace(
630
        ["UK00"], "GB"
631
    )
632
633
    p_set = []
634
    for index, row in ch4_demand_TS.iterrows():
635
        normalized_TS_df = normalized_ch4_demandTS.loc[
636
            :,
637
            normalized_ch4_demandTS.columns.str.contains(row["Node/Line"][:2]),
638
        ]
639
        p_set.append(
640
            (
641
                normalized_TS_df[normalized_TS_df.columns[0]]
642
                * row["GlobD_2035"]
643
            ).tolist()
644
        )
645
646
    ch4_demand_TS["p_set"] = p_set
647
    ch4_demand_TS["temp_id"] = 1
648
    ch4_demand_TS = ch4_demand_TS.drop(
649
        columns=["Node/Line", "GlobD_2035", "bus", "carrier"]
650
    )
651
652
    # Insert data to DB
653
    ch4_demand_TS.to_sql(
654
        targets["load_timeseries"]["table"],
655
        db.engine(),
656
        schema=targets["load_timeseries"]["schema"],
657
        index=False,
658
        if_exists="append",
659
    )
660
661
662
def calc_ch4_storage_capacities():
663
    target_file = (
664
        Path(".") / "datasets" / "gas_data" / "data" / "IGGIELGN_Storages.csv"
665
    )
666
667
    ch4_storage_capacities = pd.read_csv(
668
        target_file,
669
        delimiter=";",
670
        decimal=".",
671
        usecols=["country_code", "param"],
672
    )
673
674
    ch4_storage_capacities = ch4_storage_capacities[
675
        ch4_storage_capacities["country_code"].isin(countries)
676
    ]
677
678
    map_countries_scigrid = {
679
        "AT": "AT00",
680
        "BE": "BE00",
681
        "CZ": "CZ00",
682
        "DK": "DKE1",
683
        "EE": "EE00",
684
        "EL": "GR00",
685
        "ES": "ES00",
686
        "FI": "FI00",
687
        "FR": "FR00",
688
        "GB": "UK00",
689
        "IT": "ITCN",
690
        "LT": "LT00",
691
        "LV": "LV00",
692
        "MT": "MT00",
693
        "NL": "NL00",
694
        "PL": "PL00",
695
        "PT": "PT00",
696
        "SE": "SE01",
697
    }
698
699
    # Define new columns
700
    max_workingGas_M_m3 = []
701
    end_year = []
702
703
    for index, row in ch4_storage_capacities.iterrows():
704
        param = ast.literal_eval(row["param"])
705
        end_year.append(param["end_year"])
706
        max_workingGas_M_m3.append(param["max_workingGas_M_m3"])
707
708
    end_year = [float("inf") if x is None else x for x in end_year]
709
    ch4_storage_capacities = ch4_storage_capacities.assign(end_year=end_year)
710
    ch4_storage_capacities = ch4_storage_capacities[
711
        ch4_storage_capacities["end_year"] >= 2035
712
    ]
713
714
    # Calculate e_nom
715
    conv_factor = (
716
        10830  # M_m3 to MWh - gross calorific value = 39 MJ/m3 (eurogas.org)
717
    )
718
    ch4_storage_capacities["e_nom"] = [
719
        conv_factor * i for i in max_workingGas_M_m3
720
    ]
721
722
    ch4_storage_capacities.drop(
723
        ["param", "end_year"],
724
        axis=1,
725
        inplace=True,
726
    )
727
728
    ch4_storage_capacities["Country"] = ch4_storage_capacities[
729
        "country_code"
730
    ].map(map_countries_scigrid)
731
    ch4_storage_capacities = ch4_storage_capacities.groupby(
732
        ["country_code"]
733
    ).agg(
734
        {
735
            "e_nom": "sum",
736
            "Country": "first",
737
        },
738
    )
739
740
    ch4_storage_capacities = ch4_storage_capacities.drop(["RU"])
741
    ch4_storage_capacities.loc[:, "bus"] = (
742
        get_foreign_gas_bus_id()
743
        .loc[ch4_storage_capacities.loc[:, "Country"]]
744
        .values
745
    )
746
747
    return ch4_storage_capacities
748
749
750
def insert_storage(ch4_storage_capacities):
751
    sources = config.datasets()["gas_neighbours"]["sources"]
752
    targets = config.datasets()["gas_neighbours"]["targets"]
753
754
    # Clean table
755
    db.execute_sql(
756
        f"""
757
        DELETE FROM {targets['stores']['schema']}.{targets['stores']['table']}
758
        WHERE "carrier" = 'CH4'
759
        AND scn_name = 'eGon2035'
760
        AND bus IN (
761
            SELECT bus_id
762
            FROM {sources['buses']['schema']}.{sources['buses']['table']}
763
            WHERE scn_name = 'eGon2035'
764
            AND country != 'DE'
765
            );
766
        """
767
    )
768
    # Add missing columns
769
    c = {"scn_name": "eGon2035", "carrier": "CH4"}
770
    ch4_storage_capacities = ch4_storage_capacities.assign(**c)
771
772
    new_id = db.next_etrago_id("store")
773
    ch4_storage_capacities["store_id"] = range(
774
        new_id, new_id + len(ch4_storage_capacities)
775
    )
776
777
    ch4_storage_capacities.drop(
778
        ["Country"],
779
        axis=1,
780
        inplace=True,
781
    )
782
783
    ch4_storage_capacities = ch4_storage_capacities.reset_index(drop=True)
784
    # Insert data to db
785
    ch4_storage_capacities.to_sql(
786
        targets["stores"]["table"],
787
        db.engine(),
788
        schema=targets["stores"]["schema"],
789
        index=False,
790
        if_exists="append",
791
    )
792
793
794
def calc_global_power_to_h2_demand():
795
    """Calculates H2 demand abroad for eGon2035 scenario
796
797
    Calculates global power demand abroad linked to H2 production.
798
    The data comes from TYNDP 2020 according to NEP 2021 from the
799
    scenario 'Distributed Energy', linear interpolate between 2030
800
    and 2040.
801
802
    Returns
803
    -------
804
    pandas.DataFrame
805
        Global power-to-h2 demand per foreign node
806
807
    """
808
    sources = config.datasets()["gas_neighbours"]["sources"]
809
810
    file = zipfile.ZipFile(f"tyndp/{sources['tyndp_capacities']}")
811
    df = pd.read_excel(
812
        file.open("TYNDP-2020-Scenario-Datafile.xlsx").read(),
813
        sheet_name="Gas Data",
814
    )
815
816
    df = (
817
        df.query(
818
            'Scenario == "Distributed Energy" & '
819
            'Case == "Average" &'
820
            'Parameter == "P2H2"'
821
        )
822
        .drop(
823
            columns=[
824
                "Generator_ID",
825
                "Climate Year",
826
                "Simulation_ID",
827
                "Node 1",
828
                "Path",
829
                "Direct/Indirect",
830
                "Sector",
831
                "Note",
832
                "Category",
833
                "Case",
834
                "Scenario",
835
                "Parameter",
836
            ]
837
        )
838
        .set_index("Node/Line")
839
    )
840
841
    df_2030 = (
842
        df[df["Year"] == 2030]
843
        .rename(columns={"Value": "Value_2030"})
844
        .drop(columns=["Year"])
845
    )
846
    df_2040 = (
847
        df[df["Year"] == 2040]
848
        .rename(columns={"Value": "Value_2040"})
849
        .drop(columns=["Year"])
850
    )
851
852
    # Conversion GWh/d to MWh/h
853
    conversion_factor = 1000 / 24
854
855
    df_2035 = pd.concat([df_2040, df_2030], axis=1)
856
    df_2035["GlobD_2035"] = (
857
        (df_2035["Value_2030"] + df_2035["Value_2040"]) / 2
858
    ) * conversion_factor
859
860
    global_power_to_h2_demand = df_2035.drop(
861
        columns=["Value_2030", "Value_2040"]
862
    )
863
864
    # choose demands for considered countries
865
    global_power_to_h2_demand = global_power_to_h2_demand[
866
        (global_power_to_h2_demand.index.str[:2].isin(countries))
867
        & (global_power_to_h2_demand["GlobD_2035"] != 0)
868
    ]
869
870
    # Split in two the demands for DK and UK
871
    global_power_to_h2_demand.loc["DKW1"] = (
872
        global_power_to_h2_demand.loc["DKE1"] / 2
873
    )
874
    global_power_to_h2_demand.loc["DKE1"] = (
875
        global_power_to_h2_demand.loc["DKE1"] / 2
876
    )
877
    global_power_to_h2_demand.loc["UKNI"] = (
878
        global_power_to_h2_demand.loc["UK00"] / 2
879
    )
880
    global_power_to_h2_demand.loc["UK00"] = (
881
        global_power_to_h2_demand.loc["UK00"] / 2
882
    )
883
    global_power_to_h2_demand = global_power_to_h2_demand.reset_index()
884
885
    return global_power_to_h2_demand
886
887
888
def insert_power_to_h2_demand(global_power_to_h2_demand):
889
    """Insert H2 demands into database for eGon2035
890
891
    Detailled description
892
    This function insert data in the database and has no return.
893
894
    Parameters
895
    ----------
896
    global_power_to_h2_demand : pandas.DataFrame
897
        Global H2 demand per foreign node in 1 year
898
899
    """
900
    sources = config.datasets()["gas_neighbours"]["sources"]
901
    targets = config.datasets()["gas_neighbours"]["targets"]
902
    map_buses = get_map_buses()
903
904
    scn_name = "eGon2035"
905
    carrier = "H2_for_industry"
906
907
    db.execute_sql(
908
        f"""
909
        DELETE FROM
910
        {targets['loads']['schema']}.{targets['loads']['table']}
911
        WHERE bus IN (
912
            SELECT bus_id FROM
913
            {sources['buses']['schema']}.{sources['buses']['table']}
914
            WHERE country != 'DE'
915
            AND scn_name = '{scn_name}')
916
        AND scn_name = '{scn_name}'
917
        AND carrier = '{carrier}'
918
        """
919
    )
920
921
    # Set bus_id
922
    global_power_to_h2_demand.loc[
923
        global_power_to_h2_demand[
924
            global_power_to_h2_demand["Node/Line"].isin(map_buses.keys())
925
        ].index,
926
        "Node/Line",
927
    ] = global_power_to_h2_demand.loc[
928
        global_power_to_h2_demand[
929
            global_power_to_h2_demand["Node/Line"].isin(map_buses.keys())
930
        ].index,
931
        "Node/Line",
932
    ].map(
933
        map_buses
934
    )
935
    global_power_to_h2_demand.loc[:, "bus"] = (
936
        get_foreign_bus_id()
937
        .loc[global_power_to_h2_demand.loc[:, "Node/Line"]]
938
        .values
939
    )
940
941
    # Add missing columns
942
    c = {"scn_name": scn_name, "carrier": carrier}
943
    global_power_to_h2_demand = global_power_to_h2_demand.assign(**c)
944
945
    new_id = db.next_etrago_id("load")
946
    global_power_to_h2_demand["load_id"] = range(
947
        new_id, new_id + len(global_power_to_h2_demand)
948
    )
949
950
    global_power_to_h2_demand = global_power_to_h2_demand.rename(
951
        columns={"GlobD_2035": "p_set"}
952
    )
953
954
    # Remove useless columns
955
    global_power_to_h2_demand = global_power_to_h2_demand.drop(
956
        columns=["Node/Line"]
957
    )
958
959
    # Insert data to db
960
    global_power_to_h2_demand.to_sql(
961
        targets["loads"]["table"],
962
        db.engine(),
963
        schema=targets["loads"]["schema"],
964
        index=False,
965
        if_exists="append",
966
    )
967
968
969
def calculate_ch4_grid_capacities():
970
    """Calculates CH4 grid capacities for foreign countries based on TYNDP-data
971
972
    Parameters
973
    ----------
974
    None.
975
976
    Returns
977
    -------
978
    Neighbouring_pipe_capacities_list : pandas.DataFrame
979
980
    """
981
    sources = config.datasets()["gas_neighbours"]["sources"]
982
983
    # Download file
984
    basename = "ENTSOG_TYNDP_2020_Annex_C2_Capacities_per_country.xlsx"
985
    url = "https://www.entsog.eu/sites/default/files/2021-07/" + basename
986
    target_file = Path(".") / "datasets" / "gas_data" / basename
987
988
    urlretrieve(url, target_file)
989
    map_pipelines = {
990
        "NORDSTREAM": "RU00",
991
        "NORDSTREAM 2": "RU00",
992
        "OPAL": "DE",
993
        "YAMAL (BY)": "RU00",
994
        "Denmark": "DKE1",
995
        "Belgium": "BE00",
996
        "Netherlands": "NL00",
997
        "Norway": "NOM1",
998
        "Switzerland": "CH00",
999
        "Poland": "PL00",
1000
        "United Kingdom": "UK00",
1001
        "Germany": "DE",
1002
        "Austria": "AT00",
1003
        "France": "FR00",
1004
        "Czechia": "CZ00",
1005
        "Russia": "RU00",
1006
        "Luxemburg": "LUB1",
1007
    }
1008
1009
    grid_countries = [
1010
        "NORDSTREAM",
1011
        "NORDSTREAM 2",
1012
        "OPAL",
1013
        "YAMAL (BY)",
1014
        "Denmark",
1015
        "Belgium",
1016
        "Netherlands",
1017
        "Norway",
1018
        "Switzerland",
1019
        "Poland",
1020
        "United Kingdom",
1021
        "Germany",
1022
        "Austria",
1023
        "France",
1024
        "Czechia",
1025
        "Russia",
1026
        "Luxemburg",
1027
    ]
1028
1029
    # Read-in data from csv-file
1030
    pipe_capacities_list = pd.read_excel(
1031
        target_file,
1032
        sheet_name="Transmission Peak Capacity",
1033
        skiprows=range(4),
1034
    )
1035
    pipe_capacities_list = pipe_capacities_list[
1036
        ["To Country", "Unnamed: 3", "From Country", 2035]
1037
    ].rename(
1038
        columns={
1039
            "Unnamed: 3": "Scenario",
1040
            "To Country": "To_Country",
1041
            "From Country": "From_Country",
1042
        }
1043
    )
1044
    pipe_capacities_list["To_Country"] = pd.Series(
1045
        pipe_capacities_list["To_Country"]
1046
    ).fillna(method="ffill")
1047
    pipe_capacities_list["From_Country"] = pd.Series(
1048
        pipe_capacities_list["From_Country"]
1049
    ).fillna(method="ffill")
1050
    pipe_capacities_list = pipe_capacities_list[
1051
        pipe_capacities_list["Scenario"] == "Advanced"
1052
    ].drop(columns={"Scenario"})
1053
    pipe_capacities_list = pipe_capacities_list[
1054
        (
1055
            (pipe_capacities_list["To_Country"].isin(grid_countries))
1056
            & (pipe_capacities_list["From_Country"].isin(grid_countries))
1057
        )
1058
        & (pipe_capacities_list[2035] != 0)
1059
    ]
1060
    pipe_capacities_list["To_Country"] = pipe_capacities_list[
1061
        "To_Country"
1062
    ].map(map_pipelines)
1063
    pipe_capacities_list["From_Country"] = pipe_capacities_list[
1064
        "From_Country"
1065
    ].map(map_pipelines)
1066
    pipe_capacities_list["countrycombination"] = pipe_capacities_list[
1067
        ["To_Country", "From_Country"]
1068
    ].apply(
1069
        lambda x: tuple(sorted([str(x.To_Country), str(x.From_Country)])),
1070
        axis=1,
1071
    )
1072
1073
    pipeline_strategies = {
1074
        "To_Country": "first",
1075
        "From_Country": "first",
1076
        2035: sum,
1077
    }
1078
1079
    pipe_capacities_list = pipe_capacities_list.groupby(
1080
        ["countrycombination"]
1081
    ).agg(pipeline_strategies)
1082
1083
    # Add manually DK-SE and AT-CH pipes (Scigrid gas data)
1084
    pipe_capacities_list.loc["(DKE1, SE02)"] = ["DKE1", "SE02", 651]
1085
    pipe_capacities_list.loc["(AT00, CH00)"] = ["AT00", "CH00", 651]
1086
1087
    # Conversion GWh/d to MWh/h
1088
    pipe_capacities_list["p_nom"] = pipe_capacities_list[2035] * (1000 / 24)
1089
1090
    # Border crossing CH4 pipelines between foreign countries
1091
1092
    Neighbouring_pipe_capacities_list = pipe_capacities_list[
1093
        (pipe_capacities_list["To_Country"] != "DE")
1094
        & (pipe_capacities_list["From_Country"] != "DE")
1095
    ].reset_index()
1096
1097
    Neighbouring_pipe_capacities_list.loc[:, "bus0"] = (
1098
        get_foreign_gas_bus_id()
1099
        .loc[Neighbouring_pipe_capacities_list.loc[:, "To_Country"]]
1100
        .values
1101
    )
1102
    Neighbouring_pipe_capacities_list.loc[:, "bus1"] = (
1103
        get_foreign_gas_bus_id()
1104
        .loc[Neighbouring_pipe_capacities_list.loc[:, "From_Country"]]
1105
        .values
1106
    )
1107
1108
    # Adjust columns
1109
    Neighbouring_pipe_capacities_list = Neighbouring_pipe_capacities_list.drop(
1110
        columns=[
1111
            "To_Country",
1112
            "From_Country",
1113
            "countrycombination",
1114
            2035,
1115
        ]
1116
    )
1117
1118
    new_id = db.next_etrago_id("link")
1119
    Neighbouring_pipe_capacities_list["link_id"] = range(
1120
        new_id, new_id + len(Neighbouring_pipe_capacities_list)
1121
    )
1122
1123
    # Border crossing CH4 pipelines between DE and neighbouring countries
1124
    DE_pipe_capacities_list = pipe_capacities_list[
1125
        (pipe_capacities_list["To_Country"] == "DE")
1126
        | (pipe_capacities_list["From_Country"] == "DE")
1127
    ].reset_index()
1128
1129
    dict_cross_pipes_DE = {
1130
        ("AT00", "DE"): "AT",
1131
        ("BE00", "DE"): "BE",
1132
        ("CH00", "DE"): "CH",
1133
        ("CZ00", "DE"): "CZ",
1134
        ("DE", "DKE1"): "DK",
1135
        ("DE", "FR00"): "FR",
1136
        ("DE", "LUB1"): "LU",
1137
        ("DE", "NL00"): "NL",
1138
        ("DE", "NOM1"): "NO",
1139
        ("DE", "PL00"): "PL",
1140
        ("DE", "RU00"): "RU",
1141
    }
1142
1143
    DE_pipe_capacities_list["country_code"] = DE_pipe_capacities_list[
1144
        "countrycombination"
1145
    ].map(dict_cross_pipes_DE)
1146
    DE_pipe_capacities_list = DE_pipe_capacities_list.set_index("country_code")
1147
1148
    schema = sources["buses"]["schema"]
1149
    table = sources["buses"]["table"]
1150
    for country_code in [e for e in countries if e not in ("GB", "SE", "UK")]:
1151
1152
        # Select cross-bording links
1153
        cap_DE = db.select_dataframe(
1154
            f"""SELECT link_id, bus0, bus1
1155
                FROM {sources['links']['schema']}.{sources['links']['table']}
1156
                    WHERE scn_name = 'eGon2035'
1157
                    AND carrier = 'CH4'
1158
                    AND (("bus0" IN (
1159
                        SELECT bus_id FROM {schema}.{table}
1160
                            WHERE country = 'DE'
1161
                            AND carrier = 'CH4'
1162
                            AND scn_name = 'eGon2035')
1163
                        AND "bus1" IN (SELECT bus_id FROM {schema}.{table}
1164
                            WHERE country = '{country_code}'
1165
                            AND carrier = 'CH4'
1166
                            AND scn_name = 'eGon2035')
1167
                    )
1168
                    OR ("bus0" IN (
1169
                        SELECT bus_id FROM {schema}.{table}
1170
                            WHERE country = '{country_code}'
1171
                            AND carrier = 'CH4'
1172
                            AND scn_name = 'eGon2035')
1173
                        AND "bus1" IN (SELECT bus_id FROM {schema}.{table}
1174
                            WHERE country = 'DE'
1175
                            AND carrier = 'CH4'
1176
                            AND scn_name = 'eGon2035'))
1177
                    )
1178
            ;"""
1179
        )
1180
1181
        cap_DE["p_nom"] = DE_pipe_capacities_list.at[
1182
            country_code, "p_nom"
1183
        ] / len(cap_DE.index)
1184
        Neighbouring_pipe_capacities_list = (
1185
            Neighbouring_pipe_capacities_list.append(cap_DE)
1186
        )
1187
1188
    # Add topo, geom and length
1189
    bus_geom = db.select_geodataframe(
1190
        """SELECT bus_id, geom
1191
        FROM grid.egon_etrago_bus
1192
        WHERE scn_name = 'eGon2035'
1193
        AND carrier = 'CH4'
1194
        """,
1195
        epsg=4326,
1196
    ).set_index("bus_id")
1197
1198
    coordinates_bus0 = []
1199
    coordinates_bus1 = []
1200
1201
    for index, row in Neighbouring_pipe_capacities_list.iterrows():
1202
        coordinates_bus0.append(bus_geom["geom"].loc[int(row["bus0"])])
1203
        coordinates_bus1.append(bus_geom["geom"].loc[int(row["bus1"])])
1204
1205
    Neighbouring_pipe_capacities_list["coordinates_bus0"] = coordinates_bus0
1206
    Neighbouring_pipe_capacities_list["coordinates_bus1"] = coordinates_bus1
1207
1208
    Neighbouring_pipe_capacities_list[
1209
        "topo"
1210
    ] = Neighbouring_pipe_capacities_list.apply(
1211
        lambda row: LineString(
1212
            [row["coordinates_bus0"], row["coordinates_bus1"]]
1213
        ),
1214
        axis=1,
1215
    )
1216
    Neighbouring_pipe_capacities_list[
1217
        "geom"
1218
    ] = Neighbouring_pipe_capacities_list.apply(
1219
        lambda row: MultiLineString([row["topo"]]), axis=1
1220
    )
1221
    Neighbouring_pipe_capacities_list[
1222
        "length"
1223
    ] = Neighbouring_pipe_capacities_list.apply(
1224
        lambda row: row["topo"].length, axis=1
1225
    )
1226
1227
    # Remove useless columns
1228
    Neighbouring_pipe_capacities_list = Neighbouring_pipe_capacities_list.drop(
1229
        columns=[
1230
            "coordinates_bus0",
1231
            "coordinates_bus1",
1232
        ]
1233
    )
1234
1235
    # Add missing columns
1236
    c = {"scn_name": "eGon2035", "carrier": "CH4", "p_min_pu": -1.0}
1237
    Neighbouring_pipe_capacities_list = (
1238
        Neighbouring_pipe_capacities_list.assign(**c)
1239
    )
1240
1241
    Neighbouring_pipe_capacities_list = (
1242
        Neighbouring_pipe_capacities_list.set_geometry("geom", crs=4326)
1243
    )
1244
1245
    return Neighbouring_pipe_capacities_list
1246
1247
1248
def tyndp_gas_generation():
1249
    """Insert data from TYNDP 2020 accordning to NEP 2021
1250
    Scenario 'Distributed Energy', linear interpolate between 2030 and 2040
1251
1252
    Returns
1253
    -------
1254
    None.
1255
    """
1256
    capacities = calc_capacities()
1257
    insert_generators(capacities, "eGon2035")
1258
1259
    ch4_storage_capacities = calc_ch4_storage_capacities()
1260
    insert_storage(ch4_storage_capacities)
1261
1262
1263
def tyndp_gas_demand():
1264
    """Insert gas demands abroad for eGon2035
1265
1266
    Insert CH4 and H2 demands abroad for eGon2035 by executing the
1267
    following steps:
1268
      * CH4
1269
          * Calculation of the global CH4 demand in Norway and of the
1270
            CH4 demand profile by executing the function
1271
            :py:func:`import_ch4_demandTS`
1272
          * Calculation of the global CH4 demands by executing the
1273
            function :py:func:`calc_global_ch4_demand`
1274
          * Insertion the CH4 loads and their associated time series
1275
            in the database by executing the function
1276
            :py:func:`insert_ch4_demand`
1277
      * H2
1278
          * Calculation of the global power demand abroad linked
1279
            to H2 production by executing the function
1280
            :py:func:`calc_global_power_to_h2_demand`
1281
          * Insertion of these loads in the database by executing the
1282
            function :py:func:`insert_power_to_h2_demand`
1283
    This function insert data in the database and has no return.
1284
1285
    """
1286
    Norway_global_demand_1y, normalized_ch4_demandTS = import_ch4_demandTS()
1287
    global_ch4_demand = calc_global_ch4_demand(Norway_global_demand_1y)
1288
    insert_ch4_demand(global_ch4_demand, normalized_ch4_demandTS)
1289
1290
    global_power_to_h2_demand = calc_global_power_to_h2_demand()
1291
    insert_power_to_h2_demand(global_power_to_h2_demand)
1292
1293
1294
def grid():
1295
    """Insert data from TYNDP 2020 accordning to NEP 2021
1296
    Scenario 'Distributed Energy', linear interpolate between 2030 and 2040
1297
1298
    Returns
1299
    -------
1300
    None.
1301
    """
1302
    Neighbouring_pipe_capacities_list = calculate_ch4_grid_capacities()
1303
    insert_gas_grid_capacities(
1304
        Neighbouring_pipe_capacities_list, scn_name="eGon2035"
1305
    )
1306
1307
1308
def calculate_ocgt_capacities():
1309
    """Calculate gas turbine capacities abroad for eGon2035
1310
1311
    Calculate gas turbine capacities abroad for eGon2035 based on TYNDP
1312
    2020, scenario "Distributed Energy", interpolated between 2030 and 2040
1313
1314
    Returns
1315
    -------
1316
    df_ocgt: pandas.DataFrame
1317
        Gas turbine capacities per foreign node
1318
1319
    """
1320
    sources = config.datasets()["gas_neighbours"]["sources"]
1321
1322
    # insert installed capacities
1323
    file = zipfile.ZipFile(f"tyndp/{sources['tyndp_capacities']}")
1324
    df = pd.read_excel(
1325
        file.open("TYNDP-2020-Scenario-Datafile.xlsx").read(),
1326
        sheet_name="Capacity",
1327
    )
1328
1329
    df_ocgt = df[
1330
        [
1331
            "Node/Line",
1332
            "Scenario",
1333
            "Climate Year",
1334
            "Generator_ID",
1335
            "Year",
1336
            "Value",
1337
        ]
1338
    ]
1339
    df_ocgt = df_ocgt[
1340
        (df_ocgt["Scenario"] == "Distributed Energy")
1341
        & (df_ocgt["Climate Year"] == 1984)
1342
    ]
1343
    df_ocgt = df_ocgt[df_ocgt["Generator_ID"].str.contains("Gas")]
1344
    df_ocgt = df_ocgt[df_ocgt["Year"].isin([2030, 2040])]
1345
1346
    df_ocgt = (
1347
        df_ocgt.groupby(["Node/Line", "Year"])["Value"].sum().reset_index()
1348
    )
1349
    df_ocgt = df_ocgt.groupby([df_ocgt["Node/Line"], "Year"]).sum()
1350
    df_ocgt = df_ocgt.groupby("Node/Line")["Value"].mean()
1351
    df_ocgt = pd.DataFrame(df_ocgt, columns=["Value"]).rename(
1352
        columns={"Value": "p_nom"}
1353
    )
1354
1355
    # Choose capacities for considered countries
1356
    df_ocgt = df_ocgt[df_ocgt.index.str[:2].isin(countries)]
1357
1358
    # Attribute bus0 and bus1
1359
    df_ocgt["bus0"] = get_foreign_gas_bus_id()[df_ocgt.index]
1360
    df_ocgt["bus1"] = get_foreign_bus_id()[df_ocgt.index]
1361
    df_ocgt = df_ocgt.groupby(by=["bus0", "bus1"], as_index=False).sum()
1362
1363
    return df_ocgt
1364
1365
1366
def insert_ocgt_abroad():
1367
    """Insert gas turbine capicities abroad for eGon2035 in the database
1368
1369
    This function inserts data in the database and has no return.
1370
1371
    Parameters
1372
    ----------
1373
    df_ocgt: pandas.DataFrame
1374
        Gas turbine capacities per foreign node
1375
1376
    """
1377
    scn_name = "eGon2035"
1378
    carrier = "OCGT"
1379
1380
    # Connect to local database
1381
    engine = db.engine()
1382
1383
    df_ocgt = calculate_ocgt_capacities()
1384
1385
    df_ocgt["p_nom_extendable"] = False
1386
    df_ocgt["carrier"] = carrier
1387
    df_ocgt["scn_name"] = scn_name
1388
1389
    buses = tuple(
1390
        db.select_dataframe(
1391
            f"""SELECT bus_id FROM grid.egon_etrago_bus
1392
            WHERE scn_name = '{scn_name}' AND country != 'DE';
1393
        """
1394
        )["bus_id"]
1395
    )
1396
1397
    # Delete old entries
1398
    db.execute_sql(
1399
        f"""
1400
        DELETE FROM grid.egon_etrago_link WHERE "carrier" = '{carrier}'
1401
        AND scn_name = '{scn_name}'
1402
        AND bus0 IN {buses} AND bus1 IN {buses};
1403
        """
1404
    )
1405
1406
    # read carrier information from scnario parameter data
1407
    scn_params = get_sector_parameters("gas", scn_name)
1408
    df_ocgt["efficiency"] = scn_params["efficiency"][carrier]
1409
    df_ocgt["marginal_cost"] = (
1410
        scn_params["marginal_cost"][carrier]
1411
        / scn_params["efficiency"][carrier]
1412
    )
1413
1414
    # Adjust p_nom
1415
    df_ocgt["p_nom"] = df_ocgt["p_nom"] / scn_params["efficiency"][carrier]
1416
1417
    # Select next id value
1418
    new_id = db.next_etrago_id("link")
1419
    df_ocgt["link_id"] = range(new_id, new_id + len(df_ocgt))
1420
1421
    # Insert data to db
1422
    df_ocgt.to_sql(
1423
        "egon_etrago_link",
1424
        engine,
1425
        schema="grid",
1426
        index=False,
1427
        if_exists="append",
1428
    )
1429