@@ -223,7 +223,7 @@ def generateIterationDicts(component_dict, investmentPeriods):
223223 return df_iteration_dict , series_iteration_dict , constants_iteration_dict
224224
225225
226- def addDFVariablesToXarray (xr_ds , component_dict , df_iteration_dict ):
226+ def addDFVariablesToXarray (xr_ds , component_dict , df_iteration_dict , locations ):
227227 """Adds all variables whose data is contained in a pd.DataFrame to xarray dataset.
228228 These variables are normally regional time series (dimensions - space, time)
229229
@@ -238,10 +238,33 @@ def addDFVariablesToXarray(xr_ds, component_dict, df_iteration_dict):
238238 values - list of tuple of component class and component name
239239 :type df_iteration_dict: dict
240240
241+ :param locations: esM locations
242+ :type locations: list
243+
241244 :return: xr_ds
242245 """
246+ # Treat transmission data separately
247+ df_iteration_dict_orig = df_iteration_dict .copy ()
248+ df_iteration_dict_transm = {}
249+ df_iteration_dict = {}
250+ for variable_description , description_tuple_list in df_iteration_dict_orig .items ():
251+ for description_tuple in description_tuple_list :
252+ # check if data is transmission and time dependent
253+ if "Transmission" in description_tuple [0 ]:
254+ # add "2dim" to variable_description
255+ if variable_description not in df_iteration_dict_transm .keys ():
256+ df_iteration_dict_transm [variable_description ] = []
257+ df_iteration_dict_transm [variable_description ].append (description_tuple )
243258
244- for variable_description , description_tuple_list in df_iteration_dict .items ():
259+ else :
260+ if variable_description not in df_iteration_dict .keys ():
261+ df_iteration_dict [variable_description ] = []
262+ df_iteration_dict [variable_description ].append (description_tuple )
263+
264+ for (
265+ variable_description ,
266+ description_tuple_list ,
267+ ) in df_iteration_dict_transm .items ():
245268 df_dict = {}
246269
247270 for description_tuple in description_tuple_list :
@@ -260,22 +283,48 @@ def addDFVariablesToXarray(xr_ds, component_dict, df_iteration_dict):
260283 data = component_dict [classname ][component ][variable_description ]
261284
262285 multi_index_dataframe = data .stack ()
263- if "Period" in multi_index_dataframe .index .names :
264- multi_index_dataframe .index .set_names ("time" , level = 1 , inplace = True )
265- multi_index_dataframe .index .set_names ("space" , level = 2 , inplace = True )
286+ if set (locations ) == set (
287+ component_dict [classname ][component ][
288+ variable_description
289+ ].index .to_list ()
290+ ):
291+ multi_index_dataframe .index .set_names ("space" , level = 0 , inplace = True )
292+ multi_index_dataframe .index .set_names ("space_2" , level = 1 , inplace = True )
266293 else :
294+ # split X_X into multiindex
267295 multi_index_dataframe .index .set_names ("time" , level = 0 , inplace = True )
268296 multi_index_dataframe .index .set_names ("space" , level = 1 , inplace = True )
297+ # use regex to split via location names
298+ import re
299+
300+ pattern = re .compile ("(" + "|" .join (locations ) + ")" )
301+ space_index = multi_index_dataframe .index .get_level_values (
302+ "space"
303+ ).str .findall (pattern )
304+ time_index = multi_index_dataframe .index .get_level_values ("time" )
305+ # reconstruct multiindex
306+ multi_index_dataframe .index = pd .MultiIndex .from_tuples (
307+ [
308+ (time_index [i ], space_index [i ][0 ], space_index [i ][1 ])
309+ for i in range (len (space_index ))
310+ ],
311+ names = ["time" , "space" , "space_2" ],
312+ )
269313
270314 df_dict [df_description ] = multi_index_dataframe
271315
272316 df_variable = pd .concat (df_dict )
273317 df_variable .index .set_names ("component" , level = 0 , inplace = True )
274318
275319 ds_component = xr .Dataset ()
276- ds_component [f"ts_{ variable_description } " ] = (
277- df_variable .sort_index ().to_xarray ()
278- )
320+ if "time" in df_variable .index .names :
321+ ds_component [f"ts_{ variable_description } " ] = (
322+ df_variable .sort_index ().to_xarray ()
323+ )
324+ else :
325+ ds_component [f"2d_{ variable_description } " ] = (
326+ df_variable .sort_index ().to_xarray ()
327+ )
279328
280329 for comp in df_variable .index .get_level_values (0 ).unique ():
281330 this_class = comp .split ("; " )[0 ]
@@ -294,6 +343,61 @@ def addDFVariablesToXarray(xr_ds, component_dict, df_iteration_dict):
294343 except Exception :
295344 pass
296345
346+ for variable_description , description_tuple_list in df_iteration_dict .items ():
347+ df_dict = {}
348+
349+ for description_tuple in description_tuple_list :
350+ classname , component = description_tuple
351+
352+ df_description = f"{ classname } ; { component } "
353+
354+ # If a . is present in variable name, then the data would be
355+ # another level further in the component_dict
356+ if "." in variable_description :
357+ [var_name , subvar_name ] = variable_description .split ("." )
358+ if subvar_name .isdigit ():
359+ subvar_name = int (subvar_name )
360+ data = component_dict [classname ][component ][var_name ][subvar_name ]
361+ else :
362+ data = component_dict [classname ][component ][variable_description ]
363+
364+ multi_index_dataframe = data .stack ()
365+ if "Period" in multi_index_dataframe .index .names :
366+ multi_index_dataframe .index .set_names ("time" , level = 1 , inplace = True )
367+ multi_index_dataframe .index .set_names ("space" , level = 2 , inplace = True )
368+ else :
369+ multi_index_dataframe .index .set_names ("time" , level = 0 , inplace = True )
370+ multi_index_dataframe .index .set_names ("space" , level = 1 , inplace = True )
371+
372+ df_dict [df_description ] = multi_index_dataframe
373+
374+ # check if there is data
375+ if len (df_dict ) > 0 :
376+ df_variable = pd .concat (df_dict )
377+ df_variable .index .set_names ("component" , level = 0 , inplace = True )
378+
379+ ds_component = xr .Dataset ()
380+ ds_component [f"ts_{ variable_description } " ] = (
381+ df_variable .sort_index ().to_xarray ()
382+ )
383+
384+ for comp in df_variable .index .get_level_values (0 ).unique ():
385+ this_class = comp .split ("; " )[0 ]
386+ this_comp = comp .split ("; " )[1 ]
387+
388+ this_ds_component = (
389+ ds_component .sel (component = comp )
390+ .squeeze ()
391+ .reset_coords (names = ["component" ], drop = True )
392+ )
393+
394+ try :
395+ xr_ds [this_class ][this_comp ] = xr .merge (
396+ [xr_ds [this_class ][this_comp ], this_ds_component ]
397+ )
398+ except Exception :
399+ pass
400+
297401 return xr_ds
298402
299403
@@ -624,10 +728,27 @@ def addTimeSeriesVariableToDict(
624728 df = comp_var_xr .to_series ()
625729 elif drop_component :
626730 df = comp_var_xr .drop ("component" ).to_dataframe ().unstack (level = 1 )
731+ elif "space_2" in comp_var_xr .dims :
732+ df = comp_var_xr .to_dataframe ().squeeze ()
733+ # merge space and space_2 levels
734+ space_index = df .index .get_level_values ("space" )
735+ space_2_index = df .index .get_level_values ("space_2" )
736+ new_space_index = [
737+ f"{ space_index [i ]} _{ space_2_index [i ]} " for i in range (len (space_index ))
738+ ]
739+ df .index = pd .MultiIndex .from_tuples (
740+ [
741+ (df .index .get_level_values ("time" )[i ], new_space_index [i ])
742+ for i in range (len (new_space_index ))
743+ ],
744+ names = ["time" , "space" ],
745+ )
746+ df = df .unstack ()
747+ df = df .dropna (axis = 1 , how = "all" )
627748 else :
628749 df = comp_var_xr .to_dataframe ().unstack (level = 1 )
629750
630- if isinstance (df , pd .DataFrame ):
751+ if isinstance (df , pd .DataFrame ) and "space_2" not in comp_var_xr . dims :
631752 if len (df .columns ) > 1 :
632753 df .columns = df .columns .droplevel (0 )
633754
0 commit comments