Passed
Pull Request — dev (#826)
by
unknown
01:27
created

data.datasets.electricity_demand_timeseries.cts_buildings   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 741
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 34
eloc 405
dl 0
loc 741
rs 9.68
c 0
b 0
f 0

13 Functions

Rating   Name   Duplication   Size   Complexity  
A place_buildings_with_amenities() 0 36 3
B create_synthetic_buildings() 0 52 6
A get_peak_load_cts_buildings() 0 16 2
B calc_building_profiles() 0 27 7
A amenities_without_buildings() 0 59 2
A select_cts_buildings() 0 15 1
B cells_with_cts_demand_only() 0 64 2
A write_synthetic_buildings_to_db() 0 38 2
B cts_to_buildings() 0 102 1
A calc_building_demand_profile_share() 0 28 1
B buildings_with_amenities() 0 71 2
A calc_census_cell_share() 0 39 2
B buildings_without_amenities() 0 87 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A CtsElectricityBuildings.__init__() 0 7 1
1
from geoalchemy2.shape import to_shape
2
from sqlalchemy import Column, Float, Integer, String, func, REAL
3
from sqlalchemy.ext.declarative import declarative_base
4
import geopandas as gpd
5
import numpy as np
6
import pandas as pd
7
8
from egon.data import db
9
from egon.data.datasets import Dataset
10
from egon.data.datasets.electricity_demand import (
11
    EgonDemandRegioZensusElectricity,
12
)
13
from egon.data.datasets.electricity_demand.temporal import calc_load_curves_cts
14
from egon.data.datasets.electricity_demand_timeseries.hh_buildings import (
15
    OsmBuildingsSynthetic,
16
)
17
from egon.data.datasets.electricity_demand_timeseries.tools import (
18
    random_ints_until_sum,
19
    random_point_in_square,
20
    specific_int_until_sum,
21
    write_table_to_postgis,
22
    write_table_to_postgres,
23
)
24
from egon.data.datasets.zensus_mv_grid_districts import MapZensusGridDistricts
25
import egon.data.config
26
27
engine = db.engine()
28
Base = declarative_base()
29
30
data_config = egon.data.config.datasets()
31
RANDOM_SEED = egon.data.config.settings()["egon-data"]["--random-seed"]
32
33
import saio
34
35
# import db tables
36
saio.register_schema("openstreetmap", engine=engine)
37
saio.register_schema("society", engine=engine)
38
saio.register_schema("demand", engine=engine)
39
saio.register_schema("boundaries", engine=engine)
40
41
from saio.demand import egon_demandregio_zensus_electricity
42
from saio.openstreetmap import (
43
    osm_amenities_not_in_buildings_filtered,
44
    osm_amenities_shops_filtered,
45
    osm_buildings_filtered,
46
    osm_buildings_filtered_with_amenities,
47
    osm_buildings_synthetic,
48
)
49
from saio.society import destatis_zensus_population_per_ha
50
51
52
class EgonCtsElectricityDemandBuildingShare(Base):
53
    __tablename__ = "egon_cts_electricity_demand_building_share"
54
    __table_args__ = {"schema": "demand"}
55
56
    id = Column(Integer, primary_key=True)
57
    scenario = Column(String, primary_key=True)
58
    bus_id = Column(Integer, index=True)
59
    profile_share = Column(Float)
60
61
62
class CtsPeakLoads(Base):
63
    __tablename__ = "egon_cts_peak_loads"
64
    __table_args__ = {"schema": "demand"}
65
66
    building_id = Column(String, primary_key=True)
67
    cts_peak_load_in_w_2035 = Column(REAL)
68
    cts_peak_load_in_w_2050 = Column(REAL)
69
70
71
def amenities_without_buildings():
72
    """
73
74
    Returns
75
    -------
76
    pd.DataFrame
77
        Table of amenities without buildings
78
79
    """
80
    with db.session_scope() as session:
81
        cells_query = (
82
            session.query(
83
                destatis_zensus_population_per_ha.id.label(
84
                    "zensus_population_id"
85
                ),
86
                # TODO can be used for square around amenity
87
                #  (1 geom_amenity: 1 geom_building)
88
                #  not unique amenity_ids yet
89
                osm_amenities_not_in_buildings_filtered.geom_amenity,
90
                osm_amenities_not_in_buildings_filtered.egon_amenity_id,
91
                # egon_demandregio_zensus_electricity.demand,
92
                # # TODO can be used to generate n random buildings
93
                # # (n amenities : 1 randombuilding)
94
                # func.count(
95
                #     osm_amenities_not_in_buildings_filtered.egon_amenity_id
96
                # ).label("n_amenities_inside"),
97
                # destatis_zensus_population_per_ha.geom,
98
            )
99
            .filter(
100
                func.st_within(
101
                    osm_amenities_not_in_buildings_filtered.geom_amenity,
102
                    destatis_zensus_population_per_ha.geom,
103
                )
104
            )
105
            .filter(
106
                destatis_zensus_population_per_ha.id
107
                == egon_demandregio_zensus_electricity.zensus_population_id
108
            )
109
            .filter(
110
                egon_demandregio_zensus_electricity.sector == "service",
111
                egon_demandregio_zensus_electricity.scenario == "eGon2035"
112
                #         ).group_by(
113
                #             egon_demandregio_zensus_electricity.zensus_population_id,
114
                #             destatis_zensus_population_per_ha.geom,
115
            )
116
        )
117
    # # TODO can be used to generate n random buildings
118
    # df_cells_with_amenities_not_in_buildings = gpd.read_postgis(
119
    #     cells_query.statement, cells_query.session.bind, geom_col="geom"
120
    # )
121
    #
122
123
    # # TODO can be used for square around amenity
124
    df_synthetic_buildings_for_amenities = gpd.read_postgis(
125
        cells_query.statement,
126
        cells_query.session.bind,
127
        geom_col="geom_amenity",
128
    )
129
    return df_synthetic_buildings_for_amenities
130
131
132
def place_buildings_with_amenities(df, amenities=None, max_amenities=None):
133
    """
134
    Building centers are placed randomly within census cells.
135
    The Number of buildings is derived from n_amenity_inside, the selected
136
    method and number of amenities per building.
137
    """
138
    if isinstance(max_amenities, int):
139
        # amount of amenities is randomly generated within bounds (max_amenities,
140
        # amenities per cell)
141
        df["n_amenities_inside"] = df["n_amenities_inside"].apply(
142
            random_ints_until_sum, args=[max_amenities]
143
        )
144
    if isinstance(amenities, int):
145
        # Specific amount of amenities per building
146
        df["n_amenities_inside"] = df["n_amenities_inside"].apply(
147
            specific_int_until_sum, args=[amenities]
148
        )
149
150
    # Unnest each building
151
    df = df.explode(column="n_amenities_inside")
152
153
    # building count per cell
154
    df["building_count"] = df.groupby(["zensus_population_id"]).cumcount() + 1
155
156
    # generate random synthetic buildings
157
    edge_length = 5
158
    # create random points within census cells
159
    points = random_point_in_square(geom=df["geom"], tol=edge_length / 2)
160
161
    df.reset_index(drop=True, inplace=True)
162
    # Store center of polygon
163
    df["geom_point"] = points
164
    # Drop geometry of census cell
165
    df = df.drop(columns=["geom"])
166
167
    return df
168
169
170
def create_synthetic_buildings(df, points=None, crs="EPSG:3035"):
171
    """
172
    Synthetic buildings are generated around points.
173
    """
174
    if isinstance(points, str) and points in df.columns:
175
        points = df[points]
176
    elif isinstance(points, gpd.GeoSeries):
177
        pass
178
    else:
179
        raise ValueError("Points are of the wrong type")
180
181
    # Create building using a square around point
182
    edge_length = 5
183
    df["geom_building"] = points.buffer(distance=edge_length / 2, cap_style=3)
184
185
    if "geom_point" not in df.columns:
186
        df["geom_point"] = df["geom_building"].centroid
187
188
    # TODO Check CRS
189
    df = gpd.GeoDataFrame(
190
        df,
191
        crs=crs,
192
        geometry="geom_building",
193
    )
194
195
    # TODO remove after implementation of egon_building_id
196
    df.rename(columns={"id": "egon_building_id"}, inplace=True)
197
198
    # get max number of building ids from synthetic residential table
199
    with db.session_scope() as session:
200
        max_synth_residential_id = session.execute(
201
            func.max(OsmBuildingsSynthetic.id)
202
        ).scalar()
203
    max_synth_residential_id = int(max_synth_residential_id)
204
205
    # create sequential ids
206
    df["egon_building_id"] = range(
207
        max_synth_residential_id + 1,
208
        max_synth_residential_id + df.shape[0] + 1,
209
    )
210
211
    df["area"] = df["geom_building"].area
212
    # set building type of synthetic building
213
    df["building"] = "cts"
214
    # TODO remove in #772
215
    df = df.rename(
216
        columns={
217
            # "zensus_population_id": "cell_id",
218
            "egon_building_id": "id",
219
        }
220
    )
221
    return df
222
223
224
def buildings_with_amenities():
225
    """"""
226
227
    from saio.boundaries import egon_map_zensus_buildings_filtered_all
228
229
    with db.session_scope() as session:
230
        cells_query = (
231
            session.query(
232
                osm_buildings_filtered_with_amenities.id.label(
233
                    "egon_building_id"
234
                ),
235
                osm_buildings_filtered_with_amenities.building,
236
                osm_buildings_filtered_with_amenities.n_amenities_inside,
237
                osm_buildings_filtered_with_amenities.area,
238
                osm_buildings_filtered_with_amenities.geom_building,
239
                osm_buildings_filtered_with_amenities.geom_point,
240
                egon_map_zensus_buildings_filtered_all.zensus_population_id,
241
            )
242
            .filter(
243
                osm_buildings_filtered_with_amenities.id
244
                == egon_map_zensus_buildings_filtered_all.id
245
            )
246
            .filter(
247
                egon_demandregio_zensus_electricity.zensus_population_id
248
                == egon_map_zensus_buildings_filtered_all.zensus_population_id
249
            )
250
            .filter(
251
                egon_demandregio_zensus_electricity.sector == "service",
252
                egon_demandregio_zensus_electricity.scenario == "eGon2035",
253
            )
254
        )
255
    df_amenities_in_buildings = pd.read_sql(
256
        cells_query.statement, cells_query.session.bind, index_col=None
257
    )
258
259
    # TODO necessary?
260
    df_amenities_in_buildings["geom_building"] = df_amenities_in_buildings[
261
        "geom_building"
262
    ].apply(to_shape)
263
    df_amenities_in_buildings["geom_point"] = df_amenities_in_buildings[
264
        "geom_point"
265
    ].apply(to_shape)
266
267
    # # Count amenities per building
268
    # df_amenities_in_buildings["n_amenities_inside"] = 1
269
    # df_amenities_in_buildings[
270
    #     "n_amenities_inside"
271
    # ] = df_amenities_in_buildings.groupby("egon_building_id")[
272
    #     "n_amenities_inside"
273
    # ].transform(
274
    #     "sum"
275
    # )
276
277
    # # Only keep one building for multiple amenities
278
    # df_amenities_in_buildings = df_amenities_in_buildings.drop_duplicates(
279
    #     "egon_building_id"
280
    # )
281
    # df_amenities_in_buildings["building"] = "cts"
282
    # TODO maybe remove later
283
    df_amenities_in_buildings.sort_values("egon_building_id").reset_index(
284
        drop=True, inplace=True
285
    )
286
    df_amenities_in_buildings.rename(
287
        columns={
288
            # "zensus_population_id": "cell_id",
289
            "egon_building_id": "id"
290
        },
291
        inplace=True,
292
    )
293
294
    return df_amenities_in_buildings
295
296
297
# TODO maybe replace with tools.write_table_to_db
298
def write_synthetic_buildings_to_db(df_synthetic_buildings):
299
    """"""
300
    if not "geom_point" in df_synthetic_buildings.columns:
301
        df_synthetic_buildings["geom_point"] = df_synthetic_buildings[
302
            "geom_building"
303
        ].centroid
304
305
    df_synthetic_buildings = df_synthetic_buildings.rename(
306
        columns={
307
            "zensus_population_id": "cell_id",
308
            "egon_building_id": "id",
309
        }
310
    )
311
    # Only take existing columns
312
    columns = [
313
        column.key for column in OsmBuildingsSynthetic.__table__.columns
314
    ]
315
    df_synthetic_buildings = df_synthetic_buildings.loc[:, columns]
316
317
    dtypes = {i: OsmBuildingsSynthetic.__table__.columns[i].type for i in OsmBuildingsSynthetic.__table__.columns.keys()}
318
319
    # Write new buildings incl coord into db
320
    df_synthetic_buildings.to_postgis(
321
        name=OsmBuildingsSynthetic.__tablename__,
322
        con=engine,
323
        if_exists="append",
324
        # schema="openstreetmap",
325
        schema=OsmBuildingsSynthetic.__table_args__["schema"],
326
        # dtype={
327
        #     "id": OsmBuildingsSynthetic.id.type,
328
        #     "cell_id": OsmBuildingsSynthetic.cell_id.type,
329
        #     "geom_building": OsmBuildingsSynthetic.geom_building.type,
330
        #     "geom_point": OsmBuildingsSynthetic.geom_point.type,
331
        #     "n_amenities_inside": OsmBuildingsSynthetic.n_amenities_inside.type,
332
        #     "building": OsmBuildingsSynthetic.building.type,
333
        #     "area": OsmBuildingsSynthetic.area.type,
334
        # },
335
        dtype=dtypes,
336
    )
337
338
339
def buildings_without_amenities():
340
    """ """
341
    from saio.boundaries import egon_map_zensus_buildings_filtered_all
342
343
    # buildings_filtered in cts-demand-cells without amenities
344
    with db.session_scope() as session:
345
346
        # Synthetic Buildings
347
        q_synth_buildings = session.query(
348
            osm_buildings_synthetic.cell_id.cast(Integer).label(
349
                "zensus_population_id"
350
            ),
351
            osm_buildings_synthetic.id.cast(Integer).label("id"),
352
            osm_buildings_synthetic.area.label("area"),
353
            osm_buildings_synthetic.geom_building.label("geom_building"),
354
            osm_buildings_synthetic.geom_point.label("geom_point"),
355
        )
356
357
        # Buildings filtered
358
        q_buildings_filtered = session.query(
359
            egon_map_zensus_buildings_filtered_all.zensus_population_id,
360
            osm_buildings_filtered.id,
361
            osm_buildings_filtered.area,
362
            osm_buildings_filtered.geom_building,
363
            osm_buildings_filtered.geom_point,
364
        ).filter(
365
            osm_buildings_filtered.id
366
            == egon_map_zensus_buildings_filtered_all.id
367
        )
368
369
        # Amenities + zensus_population_id
370
        q_amenities = (
371
            session.query(
372
                destatis_zensus_population_per_ha.id.label(
373
                    "zensus_population_id"
374
                ),
375
            )
376
            .filter(
377
                func.st_within(
378
                    osm_amenities_shops_filtered.geom_amenity,
379
                    destatis_zensus_population_per_ha.geom,
380
                )
381
            )
382
            .distinct(destatis_zensus_population_per_ha.id)
383
        )
384
385
        # Cells with CTS demand but without amenities
386
        q_cts_without_amenities = (
387
            session.query(
388
                egon_demandregio_zensus_electricity.zensus_population_id,
389
            )
390
            .filter(
391
                egon_demandregio_zensus_electricity.sector == "service",
392
                egon_demandregio_zensus_electricity.scenario == "eGon2035",
393
            )
394
            .filter(
395
                egon_demandregio_zensus_electricity.zensus_population_id.notin_(
396
                    q_amenities
397
                )
398
            )
399
            .distinct()
400
        )
401
402
        # Buildings filtered + synthetic buildings residential in
403
        # cells with CTS demand but without amenities
404
        cells_query = q_synth_buildings.union(q_buildings_filtered).filter(
405
            egon_map_zensus_buildings_filtered_all.zensus_population_id.in_(
406
                q_cts_without_amenities
407
            )
408
        )
409
410
    # df_buildings_without_amenities = pd.read_sql(
411
    #     cells_query.statement, cells_query.session.bind, index_col=None)
412
    df_buildings_without_amenities = gpd.read_postgis(
413
        cells_query.statement,
414
        cells_query.session.bind,
415
        geom_col="geom_building",
416
    )
417
418
    df_buildings_without_amenities = df_buildings_without_amenities.rename(
419
        columns={
420
            # "zensus_population_id": "cell_id",
421
            "egon_building_id": "id",
422
        }
423
    )
424
425
    return df_buildings_without_amenities
426
427
428
def select_cts_buildings(df_buildings_without_amenities):
429
    """ """
430
    # TODO Adapt method
431
    # Select one building each cell
432
    # take the first
433
    df_buildings_with_cts_demand = (
434
        df_buildings_without_amenities.drop_duplicates(
435
            # subset="cell_id", keep="first"
436
            subset="zensus_population_id", keep="first"
437
        ).reset_index(drop=True)
438
    )
439
    df_buildings_with_cts_demand["n_amenities_inside"] = 1
440
    df_buildings_with_cts_demand["building"] = "cts"
441
442
    return df_buildings_with_cts_demand
443
444
445
def cells_with_cts_demand_only(df_buildings_without_amenities):
446
    """"""
447
    # cells mit amenities
448
    with db.session_scope() as session:
449
        sub_query = (
450
            session.query(
451
                destatis_zensus_population_per_ha.id.label(
452
                    "zensus_population_id"
453
                ),
454
            )
455
            .filter(
456
                func.st_within(
457
                    osm_amenities_shops_filtered.geom_amenity,
458
                    destatis_zensus_population_per_ha.geom,
459
                )
460
            )
461
            .distinct(destatis_zensus_population_per_ha.id)
462
        )
463
464
        cells_query = (
465
            session.query(
466
                egon_demandregio_zensus_electricity.zensus_population_id,
467
                egon_demandregio_zensus_electricity.scenario,
468
                egon_demandregio_zensus_electricity.sector,
469
                egon_demandregio_zensus_electricity.demand,
470
                destatis_zensus_population_per_ha.geom,
471
            )
472
            .filter(
473
                egon_demandregio_zensus_electricity.sector == "service",
474
                egon_demandregio_zensus_electricity.scenario == "eGon2035",
475
            )
476
            .filter(
477
                egon_demandregio_zensus_electricity.zensus_population_id.notin_(
478
                    sub_query
479
                )
480
            )
481
            .filter(
482
                egon_demandregio_zensus_electricity.zensus_population_id
483
                == destatis_zensus_population_per_ha.id
484
            )
485
        )
486
487
    df_cts_cell_without_amenities = gpd.read_postgis(
488
        cells_query.statement,
489
        cells_query.session.bind,
490
        geom_col="geom",
491
        index_col=None,
492
    )
493
494
    # TODO maybe remove
495
    df_buildings_without_amenities = df_buildings_without_amenities.rename(
496
        columns={"cell_id": "zensus_population_id"}
497
    )
498
499
    # Census cells with only cts demand
500
    df_cells_only_cts_demand = df_cts_cell_without_amenities.loc[
501
        ~df_cts_cell_without_amenities["zensus_population_id"].isin(
502
            df_buildings_without_amenities["zensus_population_id"].unique()
503
        )
504
    ]
505
506
    df_cells_only_cts_demand.reset_index(drop=True, inplace=True)
507
508
    return df_cells_only_cts_demand
509
510
511
def calc_census_cell_share(scenario="eGon2035"):
512
    """"""
513
514
    with db.session_scope() as session:
515
        cells_query = (
516
            session.query(
517
                EgonDemandRegioZensusElectricity, MapZensusGridDistricts.bus_id
518
            )
519
            .filter(EgonDemandRegioZensusElectricity.sector == "service")
520
            .filter(EgonDemandRegioZensusElectricity.scenario == scenario)
521
            .filter(
522
                EgonDemandRegioZensusElectricity.zensus_population_id
523
                == MapZensusGridDistricts.zensus_population_id
524
            )
525
        )
526
527
    df_demand_regio_electricity_demand = pd.read_sql(
528
        cells_query.statement,
529
        cells_query.session.bind,
530
        index_col="zensus_population_id",
531
    )
532
533
    # get demand share of cell per bus
534
    # share ist für scenarios identisch
535
    df_census_share = df_demand_regio_electricity_demand[
536
        "demand"
537
    ] / df_demand_regio_electricity_demand.groupby("bus_id")[
538
        "demand"
539
    ].transform(
540
        "sum"
541
    )
542
    df_census_share = df_census_share.rename("cell_share")
543
544
    df_census_share = pd.concat(
545
        [df_census_share, df_demand_regio_electricity_demand[["bus_id", "scenario"]]], axis=1
546
    )
547
548
    df_census_share.reset_index(inplace=True)
549
    return df_census_share
550
551
552
def calc_building_demand_profile_share(df_cts_buildings, scenario="eGon2035"):
553
    """
554
    Share of cts electricity demand profile per bus for every selected building
555
    """
556
557
    def calc_building_amenity_share(df_cts_buildings):
558
        """"""
559
        df_building_amenity_share = 1 / df_cts_buildings.groupby(
560
            "zensus_population_id")["n_amenities_inside"].transform("sum")
561
        df_building_amenity_share = pd.concat(
562
            [
563
                df_building_amenity_share.rename("building_amenity_share"),
564
                df_cts_buildings[["zensus_population_id", "id"]],
565
            ],
566
            axis=1,
567
        )
568
        return df_building_amenity_share
569
570
    df_building_amenity_share = calc_building_amenity_share(df_cts_buildings)
571
572
    df_census_cell_share = calc_census_cell_share(scenario)
573
574
    df_demand_share = pd.merge(left=df_building_amenity_share, right=df_census_cell_share,
575
                               left_on="zensus_population_id", right_on="zensus_population_id")
576
    df_demand_share["profile_share"] = df_demand_share["building_amenity_share"].multiply(
577
        df_demand_share["cell_share"])
578
579
    return df_demand_share[["id", "bus_id", "scenario", "profile_share"]]
580
581
582
def calc_building_profiles(df_demand_share=None, egon_building_id=None, scenario="eGon2035"):
583
    """
584
585
    """
586
587
    if not isinstance(df_demand_share, pd.DataFrame):
588
        with db.session_scope() as session:
589
            cells_query = session.query(EgonCtsElectricityDemandBuildingShare)
590
591
        df_demand_share = pd.read_sql(
592
            cells_query.statement, cells_query.session.bind, index_col=None)
593
594
    df_cts_profiles = calc_load_curves_cts(scenario)
595
596
    # Only calculate selected building profile if egon_building_id is given
597
    if isinstance(egon_building_id, int) and egon_building_id in df_demand_share["id"]:
598
        df_demand_share = df_demand_share.loc[
599
            df_demand_share["id"] == egon_building_id]
600
601
    df_building_profiles = pd.DataFrame()
602
    for bus_id, df in df_demand_share.groupby('bus_id'):
603
        shares = df.set_index("id", drop=True)["profile_share"]
604
        profile = df_cts_profiles.loc[:, bus_id]
605
        building_profiles = profile.apply(lambda x: x * shares)
0 ignored issues
show
introduced by
The variable shares does not seem to be defined in case the for loop on line 602 is not entered. Are you sure this can never be the case?
Loading history...
606
        df_building_profiles = pd.concat([df_building_profiles, building_profiles], axis=1)
607
608
    return df_building_profiles
609
610
611
def cts_to_buildings():
612
    """"""
613
    # Buildings with amenities
614
    df_buildings_with_amenities = buildings_with_amenities()
615
616
    # Create synthetic buildings for amenites without buildings
617
    df_amenities_without_buildings = amenities_without_buildings()
618
    df_amenities_without_buildings["n_amenities_inside"] = 1
619
    df_synthetic_buildings_with_amenities = create_synthetic_buildings(
620
        df_amenities_without_buildings, points="geom_amenity"
621
    )
622
623
    # TODO write to DB and remove renaming
624
    # write_synthetic_buildings_to_db(df_synthetic_buildings_with_amenities)
625
    write_table_to_postgis(df_synthetic_buildings_with_amenities.rename(
626
        columns={
627
            "zensus_population_id": "cell_id",
628
            "egon_building_id": "id",
629
        }),
630
        OsmBuildingsSynthetic,
631
        drop=False)
632
633
    # Cells without amenities but CTS demand and buildings
634
    df_buildings_without_amenities = buildings_without_amenities()
635
636
    # TODO Fix Adhoc Bugfix duplicated buildings
637
    mask = df_buildings_without_amenities.loc[
638
        df_buildings_without_amenities['id'].isin(
639
            df_buildings_with_amenities['id'])].index
640
    df_buildings_without_amenities = df_buildings_without_amenities.drop(
641
        index=mask).reset_index(drop=True)
642
643
    df_buildings_without_amenities = select_cts_buildings(
644
        df_buildings_without_amenities
645
    )
646
    df_buildings_without_amenities["n_amenities_inside"] = 1
647
648
    # Create synthetic amenities and buildings in cells with only CTS demand
649
    df_cells_with_cts_demand_only = cells_with_cts_demand_only(
650
        df_buildings_without_amenities
651
    )
652
    # Only 1 Amenity per cell
653
    df_cells_with_cts_demand_only["n_amenities_inside"] = 1
654
    # Only 1 Amenity per Building
655
    df_cells_with_cts_demand_only = place_buildings_with_amenities(
656
        df_cells_with_cts_demand_only, amenities=1
657
    )
658
    # Leads to only 1 building per cell
659
    df_synthetic_buildings_without_amenities = (
660
        create_synthetic_buildings(
661
            df_cells_with_cts_demand_only, points="geom_point"
662
        )
663
    )
664
665
    # TODO write to DB and remove renaming
666
    # write_synthetic_buildings_to_db(df_synthetic_buildings_without_amenities)
667
    write_table_to_postgis(df_synthetic_buildings_without_amenities.rename(
668
        columns={
669
            "zensus_population_id": "cell_id",
670
            "egon_building_id": "id",
671
        }),
672
        OsmBuildingsSynthetic,
673
        drop=False)
674
675
    # Concat all buildings
676
    columns = ["zensus_population_id", "id", "geom_building", "n_amenities_inside"]
677
    # columns = ["zensus_population_id", "id", "geom_building", "n_amenities_inside", "table"]
678
    # df_buildings_with_amenities["table"] = "df_buildings_with_amenities"
679
    # df_synthetic_buildings_with_amenities["table"] = "df_synthetic_buildings_with_amenities"
680
    # df_buildings_without_amenities["table"] = "df_buildings_without_amenities"
681
    # df_synthetic_buildings_without_amenities["table"] = "df_synthetic_buildings_without_amenities"
682
683
    df_cts_buildings = pd.concat(
684
        [
685
            df_buildings_with_amenities[columns],
686
            df_synthetic_buildings_with_amenities[columns],
687
            df_buildings_without_amenities[columns],
688
            df_synthetic_buildings_without_amenities[columns],
689
        ],
690
        axis=0,
691
        ignore_index=True,
692
    )
693
    # TODO maybe remove after #772
694
    df_cts_buildings["id"] = df_cts_buildings["id"].astype(int)
695
696
    df_demand_share_2035 = calc_building_demand_profile_share(df_cts_buildings,
697
                                                         scenario="eGon2035")
698
    df_demand_share_100RE = calc_building_demand_profile_share(df_cts_buildings,
699
                                                         scenario="eGon100RE")
700
701
    df_demand_share = pd.concat([df_demand_share_2035, df_demand_share_100RE],
702
                                axis=0, ignore_index=True)
703
704
    # TODO Why are there nonunique ids?
705
    #  needs to be removed as soon as 'id' is unique
706
    df_demand_share = df_demand_share.drop_duplicates(subset="id")
707
708
    write_table_to_postgres(df_demand_share,
709
                            EgonCtsElectricityDemandBuildingShare,
710
                            drop=True)
711
712
    return df_cts_buildings, df_demand_share
713
714
715
def get_peak_load_cts_buildings():
716
717
    df_building_profiles = calc_building_profiles()
718
    df_peak_load = df_building_profiles.max(axis=1)
719
720
    CtsPeakLoads.__table__.drop(bind=engine, checkfirst=True)
721
    CtsPeakLoads.__table__.create(bind=engine, checkfirst=True)
722
723
    # Write peak loads into db
724
    with db.session_scope() as session:
725
        session.bulk_insert_mappings(
726
            CtsPeakLoads,
727
            df_peak_load.to_dict(orient="records"),
728
        )
729
730
    return df_cts_buildings, df_building_amenity_share
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable df_cts_buildings does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable df_building_amenity_share does not seem to be defined.
Loading history...
731
732
733
class CtsElectricityBuildings(Dataset):
734
    def __init__(self, dependencies):
735
        super().__init__(
736
            name="CtsElectricityBuildings",
737
            version="0.0.0.",
738
            dependencies=dependencies,
739
            tasks=(cts_to_buildings,
740
                   get_peak_load_cts_buildings,
741
                   # get_all_cts_building_profiles,
742
                   ),
743
        )
744