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

data.datasets.electricity_demand_timeseries.cts_buildings   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 744
Duplicated Lines 0 %

Importance

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