1
|
|
|
import os |
2
|
|
|
|
3
|
|
|
from sqlalchemy.ext.declarative import declarative_base |
4
|
|
|
|
5
|
|
|
|
6
|
|
|
import pandas as pd |
7
|
|
|
|
8
|
|
|
from egon.data import db |
9
|
|
|
|
10
|
|
|
|
11
|
|
|
try: |
12
|
|
|
from disaggregator import temporal |
13
|
|
|
except ImportError as e: |
14
|
|
|
pass |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
Base = declarative_base() |
18
|
|
|
|
19
|
|
|
|
20
|
|
|
def cts_demand_per_aggregation_level(aggregation_level, scenario): |
21
|
|
|
""" |
22
|
|
|
|
23
|
|
|
Description: Create dataframe assigining the CTS demand curve to individual zensus cell |
24
|
|
|
based on their respective NUTS3 CTS curve |
25
|
|
|
|
26
|
|
|
Parameters |
27
|
|
|
---------- |
28
|
|
|
aggregation_level : str |
29
|
|
|
if further processing is to be done in zensus cell level 'other' |
30
|
|
|
else 'dsitrict' |
31
|
|
|
|
32
|
|
|
Returns |
33
|
|
|
------- |
34
|
|
|
CTS_per_district : pandas.DataFrame |
35
|
|
|
if aggregation ='district' |
36
|
|
|
NUTS3 CTS profiles assigned to individual |
37
|
|
|
zensu cells and aggregated per district heat area id |
38
|
|
|
else |
39
|
|
|
empty dataframe |
40
|
|
|
CTS_per_grid : pandas.DataFrame |
41
|
|
|
if aggregation ='district' |
42
|
|
|
NUTS3 CTS profiles assigned to individual |
43
|
|
|
zensu cells and aggregated per mv grid subst id |
44
|
|
|
else |
45
|
|
|
empty dataframe |
46
|
|
|
CTS_per_zensus : pandas.DataFrame |
47
|
|
|
if aggregation ='district' |
48
|
|
|
empty dataframe |
49
|
|
|
else |
50
|
|
|
NUTS3 CTS profiles assigned to individual |
51
|
|
|
zensu population id |
52
|
|
|
|
53
|
|
|
""" |
54
|
|
|
|
55
|
|
|
demand_nuts = db.select_dataframe( |
56
|
|
|
f""" |
57
|
|
|
SELECT demand, a.zensus_population_id, b.vg250_nuts3 |
58
|
|
|
FROM demand.egon_peta_heat a |
59
|
|
|
JOIN boundaries.egon_map_zensus_vg250 b |
60
|
|
|
ON a.zensus_population_id = b.zensus_population_id |
61
|
|
|
|
62
|
|
|
WHERE a.sector = 'service' |
63
|
|
|
AND a.scenario = '{scenario}' |
64
|
|
|
ORDER BY a.zensus_population_id |
65
|
|
|
""" |
66
|
|
|
) |
67
|
|
|
|
68
|
|
|
if os.path.isfile("CTS_heat_demand_profile_nuts3.csv"): |
69
|
|
|
df_CTS_gas_2011 = pd.read_csv( |
70
|
|
|
"CTS_heat_demand_profile_nuts3.csv", index_col=0 |
71
|
|
|
) |
72
|
|
|
df_CTS_gas_2011.columns.name = "ags_lk" |
73
|
|
|
df_CTS_gas_2011.index = pd.to_datetime(df_CTS_gas_2011.index) |
74
|
|
|
df_CTS_gas_2011 = df_CTS_gas_2011.asfreq("H") |
75
|
|
|
else: |
76
|
|
|
df_CTS_gas_2011 = temporal.disagg_temporal_gas_CTS( |
77
|
|
|
use_nuts3code=True, year=2011 |
78
|
|
|
) |
79
|
|
|
df_CTS_gas_2011.to_csv("CTS_heat_demand_profile_nuts3.csv") |
80
|
|
|
|
81
|
|
|
ags_lk = pd.read_csv( |
82
|
|
|
os.path.join( |
83
|
|
|
os.getcwd(), |
84
|
|
|
"demandregio-disaggregator/disaggregator/disaggregator/data_in/regional", |
85
|
|
|
"t_nuts3_lk.csv", |
86
|
|
|
), |
87
|
|
|
index_col=0, |
88
|
|
|
) |
89
|
|
|
ags_lk = ags_lk.drop( |
90
|
|
|
ags_lk.columns.difference(["natcode_nuts3", "ags_lk"]), axis=1 |
91
|
|
|
) |
92
|
|
|
|
93
|
|
|
CTS_profile = df_CTS_gas_2011.transpose() |
94
|
|
|
CTS_profile.reset_index(inplace=True) |
95
|
|
|
CTS_profile.ags_lk = CTS_profile.ags_lk.astype(int) |
96
|
|
|
CTS_profile = pd.merge(CTS_profile, ags_lk, on="ags_lk", how="inner") |
97
|
|
|
CTS_profile.set_index("natcode_nuts3", inplace=True) |
98
|
|
|
CTS_profile.drop("ags_lk", axis=1, inplace=True) |
99
|
|
|
|
100
|
|
|
CTS_per_zensus = pd.merge( |
101
|
|
|
demand_nuts[["zensus_population_id", "vg250_nuts3"]], |
102
|
|
|
CTS_profile, |
103
|
|
|
left_on="vg250_nuts3", |
104
|
|
|
right_on=CTS_profile.index, |
105
|
|
|
how="left", |
106
|
|
|
) |
107
|
|
|
|
108
|
|
|
CTS_per_zensus = CTS_per_zensus.drop("vg250_nuts3", axis=1) |
109
|
|
|
|
110
|
|
|
if aggregation_level == "district": |
111
|
|
|
district_heating = db.select_dataframe( |
112
|
|
|
f""" |
113
|
|
|
SELECT area_id, zensus_population_id |
114
|
|
|
FROM demand.egon_map_zensus_district_heating_areas |
115
|
|
|
WHERE scenario = '{scenario}' |
116
|
|
|
""" |
117
|
|
|
) |
118
|
|
|
|
119
|
|
|
CTS_per_district = pd.merge( |
120
|
|
|
CTS_per_zensus, |
121
|
|
|
district_heating, |
122
|
|
|
on="zensus_population_id", |
123
|
|
|
how="inner", |
124
|
|
|
) |
125
|
|
|
CTS_per_district.set_index("area_id", inplace=True) |
126
|
|
|
CTS_per_district.drop("zensus_population_id", axis=1, inplace=True) |
127
|
|
|
|
128
|
|
|
CTS_per_district = CTS_per_district.groupby(lambda x: x, axis=0).sum() |
129
|
|
|
CTS_per_district = CTS_per_district.transpose() |
130
|
|
|
CTS_per_district = CTS_per_district.apply(lambda x: x / x.sum()) |
131
|
|
|
CTS_per_district.columns.name = "area_id" |
132
|
|
|
CTS_per_district.reset_index(drop=True, inplace=True) |
133
|
|
|
|
134
|
|
|
# mv_grid = mv_grid.set_index("zensus_population_id") |
135
|
|
|
district_heating = district_heating.set_index("zensus_population_id") |
136
|
|
|
|
137
|
|
|
mv_grid_ind = db.select_dataframe( |
138
|
|
|
f""" |
139
|
|
|
SELECT bus_id, a.zensus_population_id |
140
|
|
|
FROM boundaries.egon_map_zensus_grid_districts a |
141
|
|
|
|
142
|
|
|
LEFT JOIN demand.egon_map_zensus_district_heating_areas b |
143
|
|
|
ON a.zensus_population_id = b.zensus_population_id |
144
|
|
|
|
145
|
|
|
JOIN demand.egon_peta_heat c |
146
|
|
|
ON a.zensus_population_id = c.zensus_population_id |
147
|
|
|
|
148
|
|
|
WHERE b.scenario = '{scenario}' |
149
|
|
|
AND c.scenario = '{scenario}' |
150
|
|
|
AND c.sector = 'service' |
151
|
|
|
""" |
152
|
|
|
) |
153
|
|
|
|
154
|
|
|
CTS_per_grid = pd.merge( |
155
|
|
|
CTS_per_zensus, |
156
|
|
|
mv_grid_ind, |
157
|
|
|
on="zensus_population_id", |
158
|
|
|
how="inner", |
159
|
|
|
) |
160
|
|
|
CTS_per_grid.set_index("bus_id", inplace=True) |
161
|
|
|
CTS_per_grid.drop("zensus_population_id", axis=1, inplace=True) |
162
|
|
|
|
163
|
|
|
CTS_per_grid = CTS_per_grid.groupby(lambda x: x, axis=0).sum() |
164
|
|
|
CTS_per_grid = CTS_per_grid.transpose() |
165
|
|
|
CTS_per_grid = CTS_per_grid.apply(lambda x: x / x.sum()) |
166
|
|
|
CTS_per_grid.columns.name = "bus_id" |
167
|
|
|
CTS_per_grid.reset_index(drop=True, inplace=True) |
168
|
|
|
|
169
|
|
|
CTS_per_zensus = pd.DataFrame() |
170
|
|
|
|
171
|
|
|
else: |
172
|
|
|
CTS_per_district = pd.DataFrame() |
173
|
|
|
CTS_per_grid = pd.DataFrame() |
174
|
|
|
CTS_per_zensus.set_index("zensus_population_id", inplace=True) |
175
|
|
|
|
176
|
|
|
CTS_per_zensus = CTS_per_zensus.groupby(lambda x: x, axis=0).sum() |
177
|
|
|
CTS_per_zensus = CTS_per_zensus.transpose() |
178
|
|
|
CTS_per_zensus = CTS_per_zensus.apply(lambda x: x / x.sum()) |
179
|
|
|
CTS_per_zensus.columns.name = "zensus_population_id" |
180
|
|
|
CTS_per_zensus.reset_index(drop=True, inplace=True) |
181
|
|
|
|
182
|
|
|
return CTS_per_district, CTS_per_grid, CTS_per_zensus |
183
|
|
|
|
184
|
|
|
|
185
|
|
|
def CTS_demand_scale(aggregation_level): |
186
|
|
|
""" |
187
|
|
|
|
188
|
|
|
Description: caling the demand curves to the annual demand of the respective aggregation level |
189
|
|
|
|
190
|
|
|
|
191
|
|
|
Parameters |
192
|
|
|
---------- |
193
|
|
|
aggregation_level : str |
194
|
|
|
aggregation_level : str |
195
|
|
|
if further processing is to be done in zensus cell level 'other' |
196
|
|
|
else 'dsitrict' |
197
|
|
|
|
198
|
|
|
Returns |
199
|
|
|
------- |
200
|
|
|
CTS_per_district : pandas.DataFrame |
201
|
|
|
if aggregation ='district' |
202
|
|
|
Profiles scaled up to annual demand |
203
|
|
|
else |
204
|
|
|
0 |
205
|
|
|
CTS_per_grid : pandas.DataFrame |
206
|
|
|
if aggregation ='district' |
207
|
|
|
Profiles scaled up to annual demandd |
208
|
|
|
else |
209
|
|
|
0 |
210
|
|
|
CTS_per_zensus : pandas.DataFrame |
211
|
|
|
if aggregation ='district' |
212
|
|
|
0 |
213
|
|
|
else |
214
|
|
|
Profiles scaled up to annual demand |
215
|
|
|
|
216
|
|
|
""" |
217
|
|
|
scenarios = ["eGon2035", "eGon100RE"] |
218
|
|
|
|
219
|
|
|
CTS_district = pd.DataFrame() |
220
|
|
|
CTS_grid = pd.DataFrame() |
221
|
|
|
CTS_zensus = pd.DataFrame() |
222
|
|
|
|
223
|
|
|
for scenario in scenarios: |
224
|
|
|
( |
225
|
|
|
CTS_per_district, |
226
|
|
|
CTS_per_grid, |
227
|
|
|
CTS_per_zensus, |
228
|
|
|
) = cts_demand_per_aggregation_level(aggregation_level, scenario) |
229
|
|
|
CTS_per_district = CTS_per_district.transpose() |
230
|
|
|
CTS_per_grid = CTS_per_grid.transpose() |
231
|
|
|
CTS_per_zensus = CTS_per_zensus.transpose() |
232
|
|
|
|
233
|
|
|
demand = db.select_dataframe( |
234
|
|
|
f""" |
235
|
|
|
SELECT demand, zensus_population_id |
236
|
|
|
FROM demand.egon_peta_heat |
237
|
|
|
WHERE sector = 'service' |
238
|
|
|
AND scenario = '{scenario}' |
239
|
|
|
ORDER BY zensus_population_id |
240
|
|
|
""" |
241
|
|
|
) |
242
|
|
|
|
243
|
|
|
if aggregation_level == "district": |
244
|
|
|
|
245
|
|
|
district_heating = db.select_dataframe( |
246
|
|
|
f""" |
247
|
|
|
SELECT area_id, zensus_population_id |
248
|
|
|
FROM demand.egon_map_zensus_district_heating_areas |
249
|
|
|
WHERE scenario = '{scenario}' |
250
|
|
|
""" |
251
|
|
|
) |
252
|
|
|
|
253
|
|
|
CTS_demands_district = pd.merge( |
254
|
|
|
demand, |
255
|
|
|
district_heating, |
256
|
|
|
on="zensus_population_id", |
257
|
|
|
how="inner", |
258
|
|
|
) |
259
|
|
|
CTS_demands_district.drop( |
260
|
|
|
"zensus_population_id", axis=1, inplace=True |
261
|
|
|
) |
262
|
|
|
CTS_demands_district = CTS_demands_district.groupby( |
263
|
|
|
"area_id" |
264
|
|
|
).sum() |
265
|
|
|
|
266
|
|
|
CTS_per_district = pd.merge( |
267
|
|
|
CTS_per_district, |
268
|
|
|
CTS_demands_district[["demand"]], |
269
|
|
|
how="inner", |
270
|
|
|
right_on=CTS_per_district.index, |
271
|
|
|
left_on=CTS_demands_district.index, |
272
|
|
|
) |
273
|
|
|
|
274
|
|
|
CTS_per_district = CTS_per_district.rename( |
275
|
|
|
columns={"key_0": "area_id"} |
276
|
|
|
) |
277
|
|
|
CTS_per_district.set_index("area_id", inplace=True) |
278
|
|
|
|
279
|
|
|
CTS_per_district = CTS_per_district[ |
280
|
|
|
CTS_per_district.columns[:-1] |
281
|
|
|
].multiply(CTS_per_district.demand, axis=0) |
282
|
|
|
|
283
|
|
|
CTS_per_district.insert(0, "scenario", scenario) |
284
|
|
|
|
285
|
|
|
CTS_district = CTS_district.append(CTS_per_district) |
286
|
|
|
CTS_district = CTS_district.sort_index() |
287
|
|
|
|
288
|
|
|
|
289
|
|
|
|
290
|
|
|
mv_grid_ind = db.select_dataframe( |
291
|
|
|
f""" |
292
|
|
|
SELECT bus_id, a.zensus_population_id |
293
|
|
|
FROM boundaries.egon_map_zensus_grid_districts a |
294
|
|
|
|
295
|
|
|
LEFT JOIN demand.egon_map_zensus_district_heating_areas b |
296
|
|
|
ON a.zensus_population_id = b.zensus_population_id |
297
|
|
|
|
298
|
|
|
JOIN demand.egon_peta_heat c |
299
|
|
|
ON a.zensus_population_id = c.zensus_population_id |
300
|
|
|
|
301
|
|
|
WHERE b.scenario = '{scenario}' |
302
|
|
|
AND c.scenario = '{scenario}' |
303
|
|
|
AND c.sector = 'service' |
304
|
|
|
""" |
305
|
|
|
) |
306
|
|
|
|
307
|
|
|
CTS_demands_grid = pd.merge( |
308
|
|
|
demand, |
309
|
|
|
mv_grid_ind[["bus_id", "zensus_population_id"]], |
310
|
|
|
on="zensus_population_id", |
311
|
|
|
how="inner", |
312
|
|
|
) |
313
|
|
|
|
314
|
|
|
CTS_demands_grid.drop("zensus_population_id", axis=1, inplace=True) |
315
|
|
|
CTS_demands_grid = CTS_demands_grid.groupby("bus_id").sum() |
316
|
|
|
|
317
|
|
|
CTS_per_grid = pd.merge( |
318
|
|
|
CTS_per_grid, |
319
|
|
|
CTS_demands_grid[["demand"]], |
320
|
|
|
how="inner", |
321
|
|
|
right_on=CTS_per_grid.index, |
322
|
|
|
left_on=CTS_demands_grid.index, |
323
|
|
|
) |
324
|
|
|
|
325
|
|
|
CTS_per_grid = CTS_per_grid.rename(columns={"key_0": "bus_id"}) |
326
|
|
|
CTS_per_grid.set_index("bus_id", inplace=True) |
327
|
|
|
|
328
|
|
|
CTS_per_grid = CTS_per_grid[CTS_per_grid.columns[:-1]].multiply( |
329
|
|
|
CTS_per_grid.demand, axis=0 |
330
|
|
|
) |
331
|
|
|
|
332
|
|
|
CTS_per_grid.insert(0, "scenario", scenario) |
333
|
|
|
|
334
|
|
|
CTS_grid = CTS_grid.append(CTS_per_grid) |
335
|
|
|
CTS_grid = CTS_grid.sort_index() |
336
|
|
|
|
337
|
|
|
CTS_per_zensus = 0 |
338
|
|
|
|
339
|
|
|
else: |
340
|
|
|
CTS_per_district = 0 |
341
|
|
|
CTS_per_grid = 0 |
342
|
|
|
|
343
|
|
|
CTS_per_zensus = pd.merge( |
344
|
|
|
CTS_per_zensus, |
345
|
|
|
demand, |
346
|
|
|
how="inner", |
347
|
|
|
right_on=CTS_per_zensus.index, |
348
|
|
|
left_on=demand.zensus_population_id, |
349
|
|
|
) |
350
|
|
|
CTS_per_zensus = CTS_per_zensus.drop("key_0", axis=1) |
351
|
|
|
CTS_per_zensus.set_index("zensus_population_id", inplace=True) |
352
|
|
|
|
353
|
|
|
CTS_per_zensus = CTS_per_zensus[ |
354
|
|
|
CTS_per_zensus.columns[:-1] |
355
|
|
|
].multiply(CTS_per_zensus.demand, axis=0) |
356
|
|
|
CTS_per_zensus.insert(0, "scenario", scenario) |
357
|
|
|
|
358
|
|
|
CTS_per_zensus.reset_index(inplace=True) |
359
|
|
|
|
360
|
|
|
CTS_zensus = CTS_zensus.append(CTS_per_grid) |
361
|
|
|
CTS_zensus = CTS_zensus.set_index("bus_id") |
362
|
|
|
CTS_zensus = CTS_zensus.sort_index() |
363
|
|
|
|
364
|
|
|
return CTS_district, CTS_grid, CTS_zensus |