TiMBA-Charts 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ import pandas as pd
2
+
3
+ fao = pd.read_csv('Forestry_subsetted_Data_reformatted.csv')
4
+
5
+ h_commodity = pd.read_csv('commodity_info.csv', encoding="ISO-8859-1")
6
+ h_commodity = h_commodity[['GFPM_Code','FAO-Code']]
7
+ h_commodity.columns = ['GFPM_Code_Commodity','FAO_Code_commodity']
8
+
9
+ h_country = pd.read_csv('country_info.csv', encoding="ISO-8859-1")
10
+ h_country = h_country[['Country-Code', 'FAOCou-Code']]
11
+ h_country.columns = ['GFPM_Code_Country','FAO_Code_Country']
12
+
13
+ fao_commodity = fao.merge(right=h_commodity, how='left',left_on='Item_Codes',right_on='FAO_Code_commodity').dropna()
14
+ fao_final = fao_commodity.merge(right=h_country, how='left',left_on='Area_Codes',right_on='FAO_Code_Country').dropna()
15
+ fao_final = fao_final.reset_index(drop=True)
16
+
17
+ fao_final_o5 = fao_final[fao_final.GFPM_Code_Country == 'o5']
18
+ print(fao_final_o5)
19
+
20
+ fao_final.to_csv('FAO_Data_py.csv')
Toolbox/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,362 @@
1
+ import plotly.graph_objects as go
2
+ import dash
3
+ import dash_bootstrap_components as dbc
4
+ from dash import dcc, html
5
+ from dash.dependencies import Input, Output, State
6
+ import webbrowser
7
+ from threading import Timer
8
+ import pandas as pd
9
+ import numpy as np
10
+ from pathlib import Path
11
+ import plotly.express as px
12
+ import textwrap
13
+
14
+ PACKAGEDIR = Path(__file__).parent.parent.absolute()
15
+
16
+ class DashboardPlotter:
17
+
18
+ def __init__(self, data):
19
+ self.data = data
20
+ self.app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
21
+ self.start = self.data['year'].min()
22
+ self.end = self.data['year'].max()
23
+ self.color_list = [
24
+ '#2A4D69', # Dunkelblau
25
+ '#4B8BBE', # Hellblau
26
+ '#D35400', # Dunkelorange
27
+ '#AAB7B8', # Grau
28
+ '#9B59B6', # Lila
29
+ '#2980B9', # Blau
30
+ '#27AE60', # Grün
31
+ '#6C757D', # Dunkelgrau
32
+ '#F1C40F', # Senfgelb
33
+ '#E67E22', # Orange
34
+ ]
35
+ self.create_layout()
36
+ self.create_callbacks()
37
+
38
+ def create_layout(self):
39
+ dropdown_style = {'height': '30px','marginBottom': '10px'}
40
+ self.app.layout = dbc.Container([
41
+ dbc.Row([
42
+ dbc.Col(width=5), # Leere Spalte für den linken Rand
43
+ dbc.Col(
44
+ html.Img(src="https://raw.githubusercontent.com/TI-Forest-Sector-Modelling/TiMBA/ToolBox_implementation_cm/images/timba_dashboard_logo.png",
45
+ style={'height': '90px', 'width': 'auto'}),
46
+ width=1
47
+ ),
48
+ dbc.Col(
49
+ #html.H1("TiMBA Dashboard", className="text-center mb-4"), width=10
50
+ )
51
+ ]),
52
+ dbc.Row([
53
+ dbc.Col([
54
+ dbc.Card([
55
+ dbc.CardBody([
56
+ html.H4("Filters", className="card-title"),
57
+ dcc.Dropdown(id='region-dropdown',
58
+ options=[{'label': i, 'value': i} for i in sorted(self.data['ISO3'].dropna().unique())],
59
+ multi=True,
60
+ placeholder="Select Country...",
61
+ style=dropdown_style),
62
+ dcc.Dropdown(id='continent-dropdown',
63
+ options=[{'label': i, 'value': i} for i in sorted(self.data['Continent'].dropna().unique())],
64
+ placeholder="Select Continent...",
65
+ multi=True,
66
+ style=dropdown_style),
67
+ dcc.Dropdown(id='domain-dropdown',
68
+ options=[{'label': i, 'value': i} for i in sorted(self.data['domain'].dropna().unique())],
69
+ placeholder="Select Domain...",
70
+ multi=True,
71
+ style=dropdown_style),
72
+ dcc.Dropdown(id='commodity-dropdown',
73
+ options=[{'label': i, 'value': i} for i in sorted(self.data['Commodity'].dropna().unique())],
74
+ placeholder="Select Commodity...",
75
+ multi=True,
76
+ style=dropdown_style),
77
+ dcc.Dropdown(id='commodity-group-dropdown',
78
+ options=[{'label': i, 'value': i} for i in self.data['Commodity_Group'].dropna().unique().tolist()],
79
+ placeholder="Select Commodity Group...",
80
+ multi=True,
81
+ style=dropdown_style),
82
+ dcc.Dropdown(id='scenario-filter',
83
+ options=[{'label': i, 'value': i} for i in self.data['Scenario'].unique()],
84
+ placeholder="Select Scenario...",
85
+ multi=True,
86
+ style=dropdown_style),
87
+ html.Button("Download CSV", id="btn_csv"),
88
+ dcc.Download(id="download-dataframe-csv"),
89
+ ])
90
+ ], className="mb-4", style={'white': 'white'}), #filter box
91
+ dbc.Card([
92
+ dbc.CardBody([
93
+ dcc.Graph(id='price-plot',
94
+ config={'toImageButtonOptions': {'format': 'png', 'filename': 'price_plot'}},
95
+ style={'height': '45vh','width':'46vh'})
96
+ ])
97
+ ], style={'white': 'white'}) #price box
98
+ ], width=3),
99
+ dbc.Col([
100
+ dbc.Row([
101
+ dbc.Col([
102
+ dbc.Card([
103
+ dbc.CardBody([
104
+ dcc.Graph(id='quantity-plot',
105
+ config={'toImageButtonOptions': {'format': 'png', 'filename': 'quantity_plot'}},
106
+ style={'height': '84.5vh'})
107
+ ])
108
+ ], style={'backgroundColor': 'white'}) #mittelbox
109
+ ], width=8), # Breite auf 8 reduziert
110
+ dbc.Col([
111
+ dbc.Card([
112
+ dbc.CardBody([
113
+ dcc.Graph(id='forstock-plot', # Geändert: ID auf 'forstock-plot'
114
+ config={'toImageButtonOptions': {'format': 'png'}},
115
+ style={'height': '39vh'})
116
+ ])
117
+ ], style={'backgroundColor': 'white', 'marginBottom': '20px'}), # Abstand hinzugefügt
118
+ dbc.Card([
119
+ dbc.CardBody([
120
+ html.H5("Filter for Worldmap", className="card-title"),
121
+ #html.H6("Scenario Filter", className="card-title"), # Titel für den Scenario-Filter
122
+ #html.H6("Year Filter", className="card-title"), # Titel für den Year-Filter
123
+ dcc.Dropdown(
124
+ id='year-filter',
125
+ options=[{'label': i, 'value': i} for i in sorted(self.data['year'].unique())],
126
+ placeholder="Select Year...",
127
+ style=dropdown_style
128
+ ),
129
+ dcc.Graph(id='world-map', # Geändert: ID auf 'world-map'
130
+ config={'toImageButtonOptions': {'format': 'png'}},
131
+ style={'height': '31.75vh'})
132
+ ])
133
+ ], style={'backgroundColor': 'white'})
134
+ ], width=4), # Breite auf 4 gesetzt
135
+ ]),
136
+ ], width=9)
137
+ ])
138
+ ], fluid=True, style={'backgroundColor': 'white'}) #gesamthintergrund
139
+
140
+ def create_callbacks(self):
141
+ @self.app.callback(
142
+ [Output('quantity-plot', 'figure'),
143
+ Output('price-plot', 'figure'),
144
+ Output('forstock-plot', 'figure')],
145
+ [Input('region-dropdown', 'value'),
146
+ Input('continent-dropdown', 'value'),
147
+ Input('domain-dropdown', 'value'),
148
+ Input('commodity-dropdown', 'value'),
149
+ Input('commodity-group-dropdown', 'value'),
150
+ Input('scenario-filter', 'value')]
151
+ )
152
+ def update_plots(region, continent, domain, commodity, commodity_group,scenario):
153
+ return self.update_plot_data(region, continent, domain, commodity, commodity_group,scenario)
154
+
155
+ @self.app.callback(
156
+ Output('world-map', 'figure'),
157
+ [Input('scenario-filter', 'value'),
158
+ Input('year-filter', 'value'),
159
+ Input('region-dropdown', 'value'),
160
+ Input('continent-dropdown', 'value'),
161
+ Input('domain-dropdown', 'value'),
162
+ Input('commodity-dropdown', 'value'),
163
+ Input('commodity-group-dropdown', 'value')]
164
+ )
165
+ def update_world_map(scenario, year, region, continent, domain, commodity, commodity_group):
166
+ return self.create_world_map(region, continent, domain, commodity, commodity_group, scenario, year)
167
+
168
+ @self.app.callback(
169
+ Output("download-dataframe-csv", "data"),
170
+ Input("btn_csv", "n_clicks"),
171
+ [State('region-dropdown', 'value'),
172
+ State('continent-dropdown', 'value'),
173
+ State('domain-dropdown', 'value'),
174
+ State('commodity-dropdown', 'value'),
175
+ State('commodity-group-dropdown', 'value'),
176
+ State('scenario-filter', 'value')], # Geändert von Input zu State
177
+ prevent_initial_call=True
178
+ )
179
+ def func(n_clicks, region, continent, domain, commodity, commodity_group, scenario):
180
+ if n_clicks is None:
181
+ raise dash.exceptions.PreventUpdate
182
+ filtered_data = self.filter_data(region, continent, domain, commodity, commodity_group, scenario)
183
+ return dcc.send_data_frame(filtered_data.to_csv, "filtered_data.csv")
184
+
185
+
186
+ def filter_data(self, region, continent, domain, commodity, commodity_group, scenario):
187
+ filtered_data = self.data
188
+ if region and isinstance(region, list):
189
+ filtered_data = filtered_data[filtered_data['ISO3'].isin(region)]
190
+ if continent and isinstance(continent, list):
191
+ filtered_data = filtered_data[filtered_data['Continent'].isin(continent)]
192
+ if domain and isinstance(domain, list):
193
+ filtered_data = filtered_data[filtered_data['domain'].isin(domain)]
194
+ if commodity and isinstance(commodity, list):
195
+ filtered_data = filtered_data[filtered_data['Commodity'].isin(commodity)]
196
+ if commodity_group and isinstance(commodity_group, list):
197
+ filtered_data = filtered_data[filtered_data['Commodity_Group'].isin(commodity_group)]
198
+ if scenario and isinstance(scenario, list):
199
+ filtered_data = filtered_data[filtered_data['Scenario'].isin(scenario)]
200
+ filtered_data = self.remove_extreme_outliers(df=filtered_data, col='price')
201
+ return filtered_data
202
+
203
+ def update_plot_data(self, region, continent, domain, commodity, commodity_group, scenario):
204
+ graphic_template='plotly_white'#'plotly_dark'#'plotly_white'
205
+ filtered_data = self.filter_data(region, continent, domain, commodity, commodity_group, scenario)
206
+
207
+ # Quantity plot
208
+ grouped_data_quantity = filtered_data.groupby(['year', 'Scenario']).sum().reset_index()
209
+ grouped_data_quantity = grouped_data_quantity[(grouped_data_quantity["year"] >= self.start) & (grouped_data_quantity["year"] <= self.end)]
210
+ fig_quantity = go.Figure()
211
+ for i, scenario in enumerate(grouped_data_quantity['Scenario'].unique()):
212
+ subset = grouped_data_quantity[grouped_data_quantity['Scenario'] == scenario]
213
+ color = self.color_list[i % len(self.color_list)]
214
+ dash = 'solid' if scenario in ['Historic Data'] else 'dash'
215
+ fig_quantity.add_trace(go.Scatter(x=subset['year'], y=subset['quantity'], mode='lines',
216
+ name=f'{scenario}', line=dict(color=color, dash=dash)))
217
+ title_quantity = self.generate_title(region, continent, domain, commodity, commodity_group)
218
+ title= "Quantity by Period and Scenario for " + title_quantity
219
+ fig_quantity.update_layout(
220
+ title='<br>'.join(textwrap.wrap(title, width=90)),
221
+ xaxis_title='Year',
222
+ yaxis_title='Quantity',
223
+ yaxis=dict(rangemode='nonnegative', zeroline=True, zerolinewidth=2, zerolinecolor='LightGrey'),
224
+ legend_title='Scenario',
225
+ legend=dict(orientation="h", yanchor="top", y=-0.1, xanchor="center", x=0.5),
226
+ margin=dict(l=35, r=35, t=60, b=90),
227
+ hovermode='x unified',
228
+ template=graphic_template
229
+ )
230
+
231
+ # Price plot
232
+ grouped_data_price = filtered_data.groupby(['year', 'Scenario']).mean().reset_index()
233
+ max_year = grouped_data_price['year'].max() + 0.5
234
+
235
+ fig_price = go.Figure()
236
+ for i, scenario in enumerate(grouped_data_price['Scenario'].unique()):
237
+ subset = grouped_data_price[grouped_data_price['Scenario'] == scenario]
238
+ color = self.color_list[i % len(self.color_list)]
239
+ fig_price.add_trace(go.Bar(x=subset['price'], y=subset['year'], orientation='h',
240
+ name=f'{scenario}', marker_color=color))
241
+
242
+ title_price = f'Price by Period and Scenario'
243
+ fig_price.update_layout(
244
+ title=title_price,
245
+ xaxis_title='Price',
246
+ yaxis_title='Year',
247
+ yaxis=dict(range=[2020-0.5, max_year]),
248
+ legend_title='Scenario',
249
+ template=graphic_template,
250
+ showlegend=False,
251
+ #legend=dict(orientation="h", yanchor="top", y=-0.25, xanchor="center", x=0.5),
252
+ margin=dict(l=35, r=60, t=50, b=5),
253
+ barmode='group'
254
+ )
255
+
256
+ # ForStock plot
257
+ grouped_data_stock = filtered_data.drop(columns=['domain', 'price','quantity','CommodityCode','Commodity','Commodity_Group'])
258
+ grouped_data_stock = grouped_data_stock.drop_duplicates().reset_index(drop=True)
259
+ grouped_data_stock = grouped_data_stock.groupby(['year', 'Scenario']).agg({
260
+ 'ForStock': 'sum',
261
+ }).reset_index()
262
+ grouped_data_stock = grouped_data_stock[grouped_data_stock.Scenario!='Historic Data']
263
+ fig_stock = go.Figure()
264
+ for i, scenario in enumerate(grouped_data_stock['Scenario'].unique()):
265
+ subset = grouped_data_stock[grouped_data_stock['Scenario'] == scenario]
266
+ color = self.color_list[i+1 % len(self.color_list)]
267
+ fig_stock.add_trace(go.Bar(x=subset['year'], y=subset['ForStock'],
268
+ name=f'{scenario}', marker_color=color))
269
+
270
+ min_year = 2020 - 1
271
+ max_year = grouped_data_stock['year'].max() + 0.5
272
+
273
+ min_val = grouped_data_stock['ForStock'].min() * 0.9
274
+ max_val = grouped_data_stock['ForStock'].max() * 1.1
275
+
276
+ fig_stock.update_layout(
277
+ title='Forest Stock by Year and Scenario',
278
+ xaxis_title='Year',
279
+ xaxis=dict(range=[min_year, max_year]),
280
+ yaxis=dict(range=[min_val, max_val]),
281
+ yaxis_title='ForStock',
282
+ template=graphic_template,
283
+ showlegend=False,
284
+ #legend=dict(orientation="h", yanchor="top", y=-0.35, xanchor="center", x=0.5),
285
+ margin=dict(l=50, r=50, t=40, b=5),
286
+ barmode='group'
287
+ )
288
+
289
+ return fig_quantity, fig_price, fig_stock
290
+
291
+ def generate_title(self, region, continent, domain, commodity, commodity_group):
292
+ title_parts = []
293
+ if region:
294
+ title_parts.append(f"{region}")
295
+ if continent:
296
+ title_parts.append(f"{continent}")
297
+ if domain:
298
+ title_parts.append(f"{domain}")
299
+ if commodity:
300
+ title_parts.append(f"{commodity}")
301
+ if commodity_group:
302
+ title_parts.append(f"{commodity_group}")
303
+ title = ", ".join(title_parts) if title_parts else "all data"
304
+ clean_title = title.replace("'", "").replace("[", "").replace("]", "")
305
+ return clean_title
306
+
307
+ def create_world_map(self, region, continent, domain, commodity, commodity_group, scenario=None, year=None):
308
+ filtered_data = self.filter_data(region, continent, domain, commodity, commodity_group, scenario)
309
+ if year:
310
+ filtered_data = filtered_data[filtered_data['year']==year]
311
+ country_data = filtered_data.groupby('ISO3')['quantity'].sum().reset_index()
312
+ country_data = country_data[country_data['quantity']>=0.001].reset_index()
313
+
314
+ fig = px.choropleth(
315
+ country_data,
316
+ locations="ISO3",
317
+ color="quantity",
318
+ hover_name="ISO3",
319
+ color_continuous_scale="Greens"
320
+ )
321
+
322
+ title = 'Worldmap for '+ self.generate_title(region, continent, domain, commodity, commodity_group)
323
+ fig.update_layout(
324
+ #title= '<br>'.join(textwrap.wrap(title, width=43)),
325
+ geo=dict(
326
+ showcoastlines=True,
327
+ coastlinecolor="LightGray",
328
+ showocean=False,
329
+ oceancolor="LightBlue",
330
+ projection_type='natural earth',
331
+ # Grenzen bestimmen
332
+ lonaxis_range=[-360, 360], # Längengradbereich
333
+ lataxis_range=[-55, 55], # Breitengradbereich
334
+ ),
335
+ margin=dict(l=1, r=1, t=1, b=1), # Ränder minimieren
336
+ coloraxis_showscale=False # Legende entfernen
337
+ )
338
+
339
+ return fig
340
+
341
+ def get_last_historic_year(self):
342
+ historic_data = self.data[self.data['Scenario'] == 'Historic Data']
343
+ if not historic_data.empty:
344
+ return historic_data['year'].max()
345
+ else:
346
+ return self.data['year'].max()
347
+
348
+ def remove_extreme_outliers(self,df:pd.DataFrame,col:str,threshhold:float=50):
349
+ Q1 = df[col].quantile(0.25)
350
+ Q3 = df[col].quantile(0.75)
351
+ IQR = Q3 - Q1
352
+ outlier_threshold = threshhold * IQR
353
+ df.loc[df[col] >= outlier_threshold, col] = np.nan
354
+ return df
355
+
356
+ def open_browser(self):
357
+ webbrowser.open_new("http://localhost:8050")
358
+
359
+
360
+ def run(self):
361
+ Timer(1, self.open_browser).start()
362
+ self.app.run(host='localhost', debug=False, dev_tools_ui=False, dev_tools_hot_reload=False, port=8050)
@@ -0,0 +1,243 @@
1
+ import pickle
2
+ import pandas as pd
3
+ import numpy as np
4
+ from pathlib import Path
5
+ import os
6
+ from enum import Enum
7
+ import pickle
8
+ import gzip
9
+ import Toolbox.parameters.paths as toolbox_paths
10
+ import Toolbox.parameters.default_parameters as toolbox_parameters
11
+
12
+ class import_pkl_data:
13
+ def __init__(self, num_files_to_read:int=10,
14
+ SCENARIOPATH:Path= toolbox_paths.SCINPUTPATH,
15
+ ADDINFOPATH:Path= toolbox_paths.AIINPUTPATH):
16
+ self.num_files_to_read = num_files_to_read
17
+ self.SCENARIOPATH = SCENARIOPATH
18
+ self.ADDINFOPATH = ADDINFOPATH
19
+
20
+ def open_pickle(self, src_filepath: str):
21
+ """open pkl file
22
+ :param src_filepath: source path for pkl file
23
+ :return: object from pkl file
24
+ """
25
+ import pickle
26
+ with open(src_filepath, "rb") as pkl_file:
27
+ obj = pickle.load(pkl_file)
28
+ return obj
29
+
30
+ def read_country_data(self):
31
+ """read data additional information for country data
32
+ :return: country data
33
+ """
34
+ country_data = pd.read_csv(self.ADDINFOPATH / toolbox_paths.COUNTRYINFO, encoding = "ISO-8859-1")
35
+ country_data = country_data[["Country-Code", "ContinentNew", "Country","ISO-Code"]]
36
+ country_data.columns = ["RegionCode","Continent", "Country","ISO3"]
37
+ country_data.Country = country_data.Country.astype("category")
38
+ country_data.Continent = country_data.Continent.astype("category")
39
+ country_data.ISO3 = country_data.ISO3.astype("category")
40
+ return country_data
41
+
42
+ def read_commodity_data(self):
43
+ """read data additional information for commodity data
44
+ :return: commodity data
45
+ """
46
+ commodity_data = pd.read_csv(self.ADDINFOPATH / toolbox_paths.COMMODITYINFO , encoding = "ISO-8859-1")
47
+ commodity_data = commodity_data[["Commodity","CommodityCode","Commodity_Group"]]
48
+ commodity_data.Commodity = commodity_data.Commodity.astype("category")
49
+ commodity_data.CommodityCode = commodity_data.CommodityCode.astype("category")
50
+ commodity_data.Commodity_Group = commodity_data.Commodity_Group.astype("category")
51
+ return commodity_data
52
+
53
+ def read_historic_data(self):
54
+ data = pd.read_csv(self.ADDINFOPATH / toolbox_paths.HISTINFO)
55
+ data = self.downcasting(data)
56
+ return data
57
+
58
+ def downcasting(self, data: pd.DataFrame):
59
+ data.RegionCode = data.RegionCode.astype("category")
60
+ data.CommodityCode = data.CommodityCode.astype("category")
61
+ data.domain = data.domain.astype("category")
62
+ data.price = data.price.astype("float32")
63
+ data.quantity = data.quantity.astype("float32")
64
+ data.Period = data.Period.astype("int16")
65
+ data.year = data.year.astype("int16")
66
+ data.Scenario = data.Scenario.astype("category")
67
+ data.Model = data.Model.astype("category")
68
+ return data
69
+
70
+ def add_consumption(self, data):
71
+ data["quantity"] = (data["quantity_ManufactureCost"] +
72
+ data["quantity_Supply"] -
73
+ data["quantity_TransportationExport"] +
74
+ data["quantity_TransportationImport"])
75
+ data.loc[data["quantity"] < 0, "quantity"] = 0
76
+ data["price"] = (((data["quantity_ManufactureCost"] * data["price_ManufactureCost"]) +
77
+ (data["quantity_Supply"] * data["price_Supply"]) -
78
+ (data["quantity_TransportationExport"] * data["price_TransportationExport"]) +
79
+ (data["quantity_TransportationImport"]* data["price_TransportationImport"]))/
80
+ data["quantity"])
81
+ data["price"] = 0
82
+ data["domain"] = "Consumption"
83
+ return data
84
+
85
+ def add_net_exports(self, data):
86
+ data["quantity"] = (data["quantity_TransportationExport"] -
87
+ data["quantity_TransportationImport"])
88
+ data["price"] = data["price_TransportationExport"]
89
+ data["domain"] = "Net Exports"
90
+ return data
91
+
92
+ def add_net_imports(self, data):
93
+ data["quantity"] = (data["quantity_TransportationImport"] -
94
+ data["quantity_TransportationExport"])
95
+ data["price"] = data["price_TransportationImport"]
96
+ data["domain"] = "Net Imports"
97
+ return data
98
+
99
+ def add_production(self, data):
100
+ data["quantity"] = (data["quantity_ManufactureCost"] + data["quantity_Supply"])
101
+ data["price"] = (((data["quantity_ManufactureCost"] * data["price_ManufactureCost"]) +
102
+ (data["quantity_Supply"] * data["price_Supply"])) / data["quantity"])
103
+ # if data["price"].mean() <=0:
104
+ # data["price"] = 0
105
+ data["domain"] = "Production"
106
+ return data
107
+
108
+ def concat_calc_domains(self,origin_data:pd.DataFrame,calc_data:pd.DataFrame):
109
+ calc_data = calc_data[['RegionCode','CommodityCode','Period','year','domain','price','quantity']].reset_index(drop=True)
110
+ result_df = pd.concat([origin_data, calc_data], axis=0).reset_index(drop=True)
111
+ return result_df
112
+
113
+ def add_calculated_domains(self,data:pd.DataFrame):
114
+ pivoted_price = data["data_periods"].pivot(index=["RegionCode", "CommodityCode", "Period", "year"],
115
+ columns="domain",
116
+ values="price").add_prefix("price_")
117
+ pivoted_quantity = data["data_periods"].pivot(index=["RegionCode", "CommodityCode", "Period", "year"],
118
+ columns="domain",
119
+ values="quantity").add_prefix("quantity_")
120
+ pivoted_df = pd.concat([pivoted_price, pivoted_quantity], axis=1).reset_index()
121
+
122
+ calculated_functions = [#"add_consumption",
123
+ "add_net_exports",
124
+ "add_net_imports",
125
+ #"add_production",
126
+ ]
127
+ for method_name in calculated_functions:
128
+ calc_df = getattr(self, method_name)(data=pivoted_df)
129
+ data["data_periods"] = self.concat_calc_domains(origin_data=data["data_periods"], calc_data=calc_df)
130
+
131
+ return data["data_periods"]
132
+
133
+ def concat_scenarios(self, data: pd.DataFrame, sc_name:str, data_prev: pd.DataFrame, ID: int):
134
+ """concat_scenarios, add scenario name from pkl file to data frames
135
+ :param data: dictionary of the data container
136
+ :param sc_name: scenario name from file name in dictionary
137
+ """
138
+ data["data_periods"] = self.add_calculated_domains(data=data)
139
+ try:
140
+ for key in data: #loop through all data from datacontainer
141
+ data[key][toolbox_parameters.column_name_scenario] = sc_name
142
+ data[key][toolbox_parameters.column_name_model] = toolbox_parameters.model_name
143
+ #data[key][parameters.column_name_id.value] = ID
144
+ if data_prev != []:
145
+ data[key] = pd.concat([data_prev[key], data[key]], axis=0)
146
+ except KeyError:
147
+ pass
148
+
149
+ def combined_data(self):
150
+ """loop trough all input files in input directory
151
+ """
152
+ scenario_path = self.SCENARIOPATH
153
+ num_files_to_read = self.num_files_to_read
154
+ pkl_files = [
155
+ Path(scenario_path) / file
156
+ for file in os.listdir(scenario_path)
157
+ if file.endswith(".pkl")
158
+ ]
159
+ sorted_files = sorted(pkl_files, key=lambda x: x.stat().st_mtime, reverse=True)
160
+ newest_files = sorted_files[:num_files_to_read]
161
+
162
+ data = []
163
+ data_prev = []
164
+ ID = 1
165
+ for scenario_files in newest_files:
166
+ src_filepath = scenario_path / scenario_files
167
+ print(src_filepath)
168
+ scenario_name = str(scenario_files)[str(scenario_files).rfind(toolbox_parameters.seperator_scenario_name)+3
169
+ :-4]
170
+ try:
171
+ with gzip.open(src_filepath,'rb') as f:
172
+ if type(f) == gzip.GzipFile:
173
+ data = pickle.load(f)
174
+ data['data_periods'] = data['data_periods'][['RegionCode','CommodityCode','Period','year','domain','price','quantity']]
175
+ self.concat_scenarios(data=data, sc_name=scenario_name, data_prev=data_prev, ID=ID)
176
+ except gzip.BadGzipFile:
177
+ pass
178
+ except pickle.UnpicklingError:
179
+ pass
180
+ except PermissionError:
181
+ pass
182
+ except ValueError:
183
+ pass
184
+
185
+ data_prev = data
186
+ ID += 1
187
+
188
+ data_prev["data_periods"] = self.downcasting(data_prev["data_periods"])
189
+ try:
190
+ data = self.read_historic_data()
191
+ except FileNotFoundError:
192
+ data = pd.DataFrame()
193
+ country_data = self.read_country_data()
194
+ commodity_data = self.read_commodity_data()
195
+ forest_data = data_prev['Forest']
196
+ forest_data = forest_data[['Scenario','RegionCode','Period','ForStock','ForArea']]
197
+ forest_data = forest_data.drop_duplicates(subset=['Scenario', 'RegionCode', 'Period'], keep='first')
198
+ data_prev["data_periods"] = pd.merge(data_prev["data_periods"], forest_data, how='left', on=['Scenario','RegionCode','Period'])
199
+ data_prev["data_periods"] = pd.concat([data_prev["data_periods"], data], axis=0)
200
+ data_prev["data_periods"] = pd.merge(data_prev["data_periods"], country_data, on="RegionCode", how="left")
201
+ data_prev["data_periods"] = pd.merge(data_prev["data_periods"], commodity_data, on="CommodityCode", how="left")
202
+ data_prev["data_periods"]["domain"] = data_prev["data_periods"]["domain"].replace({
203
+ 'ManufactureCost': 'Manufacturing',
204
+ 'TransportationExport': 'Export',
205
+ 'TransportationImport': 'Import',
206
+ })
207
+ data_prev["data_periods"] = data_prev["data_periods"][['Model','Scenario','RegionCode','Continent','Country','ISO3',
208
+ 'CommodityCode','Commodity','Commodity_Group','Period','year',
209
+ 'domain','price','quantity',
210
+ 'ForStock','ForArea',
211
+ ]]
212
+ return data_prev
213
+
214
+ def read_forest_data_gfpm(self, country_data:pd.DataFrame):
215
+ for_data_gfpm = pd.read_csv(self.ADDINFOPATH / toolbox_paths.FORESTINFO, encoding = "ISO-8859-1")
216
+
217
+ rearranged_for_data = pd.melt(for_data_gfpm, id_vars=['domain','Country'], var_name='Year',value_name='for')
218
+ rearranged_for_data = rearranged_for_data.dropna()
219
+ rearranged_for_data['Year'] = rearranged_for_data['Year'].astype(int)
220
+
221
+ foreststock = pd.DataFrame()
222
+ for domain in rearranged_for_data.domain.unique():
223
+ rearranged_for_data_domain = rearranged_for_data[rearranged_for_data['domain'] == domain].reset_index(drop=True)
224
+ if domain == 'ForArea':
225
+ rearranged_for_data_domain['ForStock'] = foreststock
226
+ else:
227
+ foreststock = rearranged_for_data_domain['for']
228
+ forest_data = rearranged_for_data_domain[['Country', 'Year', 'for', 'ForStock']]
229
+ forest_data.columns = ['Country', 'Year', 'ForArea', 'ForStock']
230
+ forest_data = pd.merge(forest_data, country_data, on= 'Country')
231
+
232
+ period_mapping = {2017: 0, 2020: 1, 2025: 2, 2030: 3, 2035: 4, 2040: 5, 2045: 6, 2050: 7, 2055: 8, 2060: 9, 2065: 10}
233
+ forest_data['Period'] = forest_data['Year'].map(period_mapping)
234
+
235
+ forest_gfpm = forest_data[['RegionCode', 'Period', 'ForStock', 'ForArea']]
236
+ forest_gfpm[toolbox_parameters.column_name_scenario]= 'world500'
237
+ forest_data['Model'] = 'GFPM'
238
+ return forest_gfpm
239
+
240
+ if __name__ == "__main__":
241
+ import_pkl = import_pkl_data()
242
+ data = import_pkl.combined_data()
243
+ print(data['data_periods'])