2525import csv
2626from itertools import zip_longest
2727import numpy as np
28+ from scipy import sparse
2829import pandas as pd
30+ import xlsxwriter
2931
3032from climada .entity .tag import Tag
3133from climada .hazard .tag import Tag as TagHaz
@@ -53,6 +55,8 @@ class Impact():
5355 tot_value (float): total exposure value affected
5456 aai_agg (float): average annual impact (aggregated)
5557 unit (str): value unit used (given by exposures unit)
58+ imp_mat (sparse.csr_matrix): matrix num_events x num_exp with impacts.
59+ only filled if save_mat is True in calc()
5660 """
5761
5862 def __init__ (self ):
@@ -68,6 +72,7 @@ def __init__(self):
6872 self .tot_value = 0
6973 self .aai_agg = 0
7074 self .unit = ''
75+ self .imp_mat = []
7176
7277 def calc_freq_curve (self , return_per = None ):
7378 """Compute impact exceedance frequency curve.
@@ -98,13 +103,14 @@ def calc_freq_curve(self, return_per=None):
98103
99104 return ifc
100105
101- def calc (self , exposures , impact_funcs , hazard ):
106+ def calc (self , exposures , impact_funcs , hazard , save_mat = False ):
102107 """Compute impact of an hazard to exposures.
103108
104109 Parameters:
105110 exposures (Exposures): exposures
106111 impact_funcs (ImpactFuncSet): impact functions
107112 hazard (Hazard): hazard
113+ self_mat (bool): self impact matrix: events x exposures
108114
109115 Examples:
110116 Use Entity class:
@@ -168,6 +174,9 @@ def calc(self, exposures, impact_funcs, hazard):
168174 and exposures .cover .max ():
169175 insure_flag = True
170176
177+ if save_mat :
178+ self .imp_mat = sparse .lil_matrix ((self .date .size , exposures .value .size ))
179+
171180 # 3. Loop over exposures according to their impact function
172181 tot_exp = 0
173182 for imp_fun in haz_imp :
@@ -237,6 +246,9 @@ def _exp_impact(self, exp_iimp, exposures, hazard, imp_fun, insure_flag):
237246 imp_fun (ImpactFunc): impact function instance
238247 insure_flag (bool): consider deductible and cover of exposures
239248 """
249+ if not exp_iimp .size :
250+ return
251+
240252 # get assigned centroids
241253 icens = exposures [INDICATOR_CENTR + hazard .tag .haz_type ].values [exp_iimp ]
242254
@@ -261,9 +273,11 @@ def _exp_impact(self, exp_iimp, exposures, hazard, imp_fun, insure_flag):
261273
262274 self .at_event += np .squeeze (np .asarray (np .sum (impact , axis = 1 )))
263275 self .tot_value += np .sum (exposures .value .values [exp_iimp ])
276+ if not isinstance (self .imp_mat , list ):
277+ self .imp_mat [:, exp_iimp ] = impact
264278
265279 def write_csv (self , file_name ):
266- """ Write data into csv file.
280+ """ Write data into csv file. imp_mat is not saved.
267281
268282 Parameters:
269283 file_name (str): absolute path of the file
@@ -285,6 +299,60 @@ def write_csv(self, file_name):
285299 for values in zip_longest (* csv_data ):
286300 imp_wr .writerow (values )
287301
302+ def write_excel (self , file_name ):
303+ """ Write data into Excel file. imp_mat is not saved.
304+
305+ Parameters:
306+ file_name (str): absolute path of the file
307+ """
308+ def write_col (i_col , imp_ws , xls_data ):
309+ """ Write one measure """
310+ row_ini = 1
311+ for dat_row in xls_data :
312+ imp_ws .write (row_ini , i_col , dat_row )
313+ row_ini += 1
314+
315+ imp_wb = xlsxwriter .Workbook (file_name )
316+ imp_ws = imp_wb .add_worksheet ()
317+
318+ header = ["tag_hazard" , "tag_exposure" , "tag_impact_func" ,
319+ "unit" , "tot_value" , "aai_agg" , "event_id" ,
320+ "event_name" , "event_date" , "event_frequency" ,
321+ "at_event" , "eai_exp" , "exp_lat" , "exp_lon" ]
322+ for icol , head_dat in enumerate (header ):
323+ imp_ws .write (0 , icol , head_dat )
324+ data = [self .tag ['haz' ].haz_type , self .tag ['haz' ].file_name ,
325+ self .tag ['haz' ].description ]
326+ write_col (0 , imp_ws , data )
327+ data = [self .tag ['exp' ].file_name , self .tag ['exp' ].description ]
328+ write_col (1 , imp_ws , data )
329+ data = [self .tag ['if_set' ].file_name , self .tag ['if_set' ].description ]
330+ write_col (2 , imp_ws , data )
331+ write_col (3 , imp_ws , [self .unit ])
332+ write_col (4 , imp_ws , [self .tot_value ])
333+ write_col (5 , imp_ws , [self .aai_agg ])
334+ write_col (6 , imp_ws , self .event_id )
335+ write_col (7 , imp_ws , self .event_name )
336+ write_col (8 , imp_ws , self .date )
337+ write_col (9 , imp_ws , self .frequency )
338+ write_col (10 , imp_ws , self .at_event )
339+ write_col (11 , imp_ws , self .eai_exp )
340+ write_col (12 , imp_ws , self .coord_exp [:, 0 ])
341+ write_col (13 , imp_ws , self .coord_exp [:, 1 ])
342+
343+ imp_wb .close ()
344+
345+ def write_excel_imp_mat (self , file_name ):
346+ """ Write imp_mat matrix """
347+ imp_wb = xlsxwriter .Workbook (file_name )
348+ imp_ws = imp_wb .add_worksheet ()
349+
350+ imp_ws .write (0 , 0 , "imp_matrix" )
351+ for irow in range (1 , self .imp_mat .shape [0 ]+ 1 ):
352+ for icol in range (self .imp_mat .shape [1 ]):
353+ imp_ws .write (irow , icol , self .imp_mat [irow - 1 , icol ])
354+ imp_wb .close ()
355+
288356 def read_csv (self , file_name ):
289357 """ Read csv file containing impact data generated by write_csv.
290358
@@ -315,6 +383,40 @@ def read_csv(self, file_name):
315383 self .tag ['if_set' ] = Tag (str (imp_df .tag_impact_func [0 ]),
316384 str (imp_df .tag_impact_func [1 ]))
317385
386+ def read_excel (self , file_name ):
387+ """ Read excel file containing impact data generated by write_excel.
388+
389+ Parameters:
390+ file_name (str): absolute path of the file
391+ """
392+ dfr = pd .read_excel (file_name )
393+ self .__init__ ()
394+ self .tag ['haz' ] = TagHaz ()
395+ self .tag ['haz' ].haz_type = dfr ['tag_hazard' ][0 ]
396+ self .tag ['haz' ].file_name = dfr ['tag_hazard' ][1 ]
397+ self .tag ['haz' ].description = dfr ['tag_hazard' ][2 ]
398+ self .tag ['exp' ] = Tag ()
399+ self .tag ['exp' ].file_name = dfr ['tag_exposure' ][0 ]
400+ self .tag ['exp' ].description = dfr ['tag_exposure' ][1 ]
401+ self .tag ['if_set' ] = Tag ()
402+ self .tag ['if_set' ].file_name = dfr ['tag_impact_func' ][0 ]
403+ self .tag ['if_set' ].description = dfr ['tag_impact_func' ][1 ]
404+
405+ self .unit = dfr .unit [0 ]
406+ self .tot_value = dfr .tot_value [0 ]
407+ self .aai_agg = dfr .aai_agg [0 ]
408+
409+ self .event_id = dfr .event_id [~ np .isnan (dfr .event_id .values )].values
410+ self .event_name = dfr .event_name [:self .event_id .size ].values
411+ self .date = dfr .event_date [:self .event_id .size ].values
412+ self .frequency = dfr .event_frequency [:self .event_id .size ].values
413+ self .at_event = dfr .at_event [:self .event_id .size ].values
414+
415+ self .eai_exp = dfr .eai_exp [~ np .isnan (dfr .eai_exp .values )].values
416+ self .coord_exp = np .zeros ((self .eai_exp .size , 2 ))
417+ self .coord_exp [:, 0 ] = dfr .exp_lat .values [:self .eai_exp .size ]
418+ self .coord_exp [:, 1 ] = dfr .exp_lon .values [:self .eai_exp .size ]
419+
318420 @property
319421 def coord_exp (self ):
320422 """ Return coord"""
0 commit comments