Skip to content

Commit 33c9d52

Browse files
committed
climada/engine/impact.py
1 parent 64e9c77 commit 33c9d52

File tree

1 file changed

+84
-86
lines changed

1 file changed

+84
-86
lines changed

climada/engine/impact.py

Lines changed: 84 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -10,56 +10,12 @@
1010
from climada.entity.tag import Tag
1111
from climada.hazard.tag import Tag as TagHazard
1212
from climada.util.coordinates import GridPoints
13-
import climada.util.plot as plot
13+
import climada.util.plot as u_plot
14+
from climada.util.config import CONFIG
1415

1516
LOGGER = logging.getLogger(__name__)
1617

17-
MAX_SIZE = 1.0e8
18-
""" Maximum matrix size for impact caluculation. If the matrix is bigger,
19-
it is chunked."""
20-
21-
class ImpactFreqCurve(object):
22-
""" Impact exceedence frequency curve.
23-
24-
Attributes:
25-
return_per (np.array): return period
26-
impact (np.array): impact exceeding frequency
27-
unit (str): value unit used (given by exposures unit)
28-
label (str): string describing source data
29-
"""
30-
def __init__(self):
31-
self.return_per = np.array([])
32-
self.impact = np.array([])
33-
self.unit = 'NA'
34-
self.label = ''
35-
36-
def plot(self):
37-
"""Plot impact frequency curve.
38-
39-
Returns:
40-
matplotlib.figure.Figure, [matplotlib.axes._subplots.AxesSubplot]
41-
"""
42-
graph = plot.Graph2D(self.label)
43-
graph.add_subplot('Return period (year)', 'Impact (%s)' % self.unit)
44-
graph.add_curve(self.return_per, self.impact, 'y')
45-
return graph.get_elems()
46-
47-
def plot_compare(self, ifc):
48-
"""Plot current and input impact frequency curves in a figure.
49-
50-
Returns:
51-
matplotlib.figure.Figure, [matplotlib.axes._subplots.AxesSubplot]
52-
"""
53-
if self.unit != ifc.unit:
54-
LOGGER.warning("Comparing between two different units: %s and %s",\
55-
self.unit, ifc.unit)
56-
graph = plot.Graph2D('', 2)
57-
graph.add_subplot('Return period (year)', 'Impact (%s)' % self.unit)
58-
graph.add_curve(self.return_per, self.impact, 'b', label=self.label)
59-
graph.add_curve(ifc.return_per, ifc.impact, 'r', label=ifc.label)
60-
return graph.get_elems()
61-
62-
class Impact(object):
18+
class Impact():
6319
"""Impact definition. Compute from an entity (exposures and impact
6420
functions) and hazard.
6521
@@ -92,7 +48,7 @@ def __init__(self):
9248
self.frequency = np.array([])
9349
self.tot_value = 0
9450
self.aai_agg = 0
95-
self.unit = 'NA'
51+
self.unit = ''
9652

9753
def calc_freq_curve(self):
9854
"""Compute impact exceedance frequency curve.
@@ -178,20 +134,52 @@ def calc(self, exposures, impact_funcs, hazard):
178134
# 3. Loop over exposures according to their impact function
179135
# Loop over impact functions
180136
for imp_fun in haz_imp:
181-
self.imp_fun = imp_fun
182137
# get indices of all the exposures with this impact function
183138
exp_iimp = np.where(exposures.impact_id[exp_idx] == imp_fun.id)[0]
184-
exp_step = int(MAX_SIZE/num_events)
139+
exp_step = int(CONFIG['impact']['max_matrix_size']/num_events)
185140
# separte in chunks if too many exposures
186-
i = -1
187-
for i in range(int(exp_iimp.size/exp_step)):
188-
self._exp_impact(exp_idx[exp_iimp[i*exp_step:(i+1)*exp_step]],\
141+
chk = -1
142+
for chk in range(int(exp_iimp.size/exp_step)):
143+
self._exp_impact( \
144+
exp_idx[exp_iimp[chk*exp_step:(chk+1)*exp_step]],\
189145
exposures, hazard, imp_fun, insure_flag)
190-
self._exp_impact(exp_idx[exp_iimp[(i+1)*exp_step:]],\
146+
self._exp_impact(exp_idx[exp_iimp[(chk+1)*exp_step:]],\
191147
exposures, hazard, imp_fun, insure_flag)
192148

193149
self.aai_agg = sum(self.at_event * hazard.frequency)
194150

151+
def plot_eai_exposure(self, ignore_zero=True, pop_name=True,
152+
buffer_deg=0.0, extend='neither', var_name=None,
153+
**kwargs):
154+
"""Plot expected annual impact of each exposure.
155+
156+
Parameters:
157+
ignore_zero (bool, optional): flag to indicate if zero and negative
158+
values are ignored in plot. Default: False
159+
pop_name (bool, optional): add names of the populated places
160+
buffer_deg (float, optional): border to add to coordinates.
161+
Default: 1.0.
162+
extend (str, optional): extend border colorbar with arrows.
163+
[ 'neither' | 'both' | 'min' | 'max' ]
164+
var_name (str, optional): Colorbar label
165+
kwargs (optional): arguments for hexbin matplotlib function
166+
167+
Returns:
168+
matplotlib.figure.Figure, cartopy.mpl.geoaxes.GeoAxesSubplot
169+
"""
170+
title = 'Expected annual impact'
171+
if var_name is None:
172+
var_name = 'Impact (' + self.unit + ')'
173+
if ignore_zero:
174+
pos_vals = self.eai_exp > 0
175+
else:
176+
pos_vals = np.ones((self.eai_exp.size,), dtype=bool)
177+
if 'reduce_C_function' not in kwargs:
178+
kwargs['reduce_C_function'] = np.sum
179+
return u_plot.geo_bin_from_array(self.eai_exp[pos_vals], \
180+
self.coord_exp[pos_vals], var_name, title, pop_name, buffer_deg, \
181+
extend, **kwargs)
182+
195183
def _exp_impact(self, exp_iimp, exposures, hazard, imp_fun, insure_flag):
196184
"""Compute impact for inpute exposure indexes and impact function.
197185
@@ -209,6 +197,7 @@ def _exp_impact(self, exp_iimp, exposures, hazard, imp_fun, insure_flag):
209197
inten_val = hazard.intensity[:, icens].todense()
210198
# get affected fractions
211199
fract = hazard.fraction[:, icens]
200+
# impact = fraction * mdr * value
212201
impact = fract.multiply(imp_fun.calc_mdr(inten_val)). \
213202
multiply(exposures.value[exp_iimp])
214203

@@ -226,38 +215,6 @@ def _exp_impact(self, exp_iimp, exposures, hazard, imp_fun, insure_flag):
226215
self.at_event += np.squeeze(np.asarray(np.sum(impact, axis=1)))
227216
self.tot_value += np.sum(exposures.value[exp_iimp])
228217

229-
def plot_eai_exposure(self, ignore_zero=True, pop_name=True,
230-
buffer_deg=0.0, extend='neither', var_name=None,
231-
**kwargs):
232-
"""Plot expected annual impact of each exposure.
233-
234-
Parameters:
235-
ignore_zero (bool, optional): flag to indicate if zero and negative
236-
values are ignored in plot. Default: False
237-
pop_name (bool, optional): add names of the populated places
238-
buffer_deg (float, optional): border to add to coordinates.
239-
Default: 1.0.
240-
extend (str, optional): extend border colorbar with arrows.
241-
[ 'neither' | 'both' | 'min' | 'max' ]
242-
var_name (str, optional): Colorbar label
243-
kwargs (optional): arguments for hexbin matplotlib function
244-
245-
Returns:
246-
matplotlib.figure.Figure, cartopy.mpl.geoaxes.GeoAxesSubplot
247-
"""
248-
title = 'Expected annual impact'
249-
if var_name is None:
250-
var_name = 'Impact (' + self.unit + ')'
251-
if ignore_zero:
252-
pos_vals = self.eai_exp > 0
253-
else:
254-
pos_vals = np.ones((self.eai_exp.size,), dtype=bool)
255-
if 'reduce_C_function' not in kwargs:
256-
kwargs['reduce_C_function'] = np.sum
257-
return plot.geo_bin_from_array(self.eai_exp[pos_vals], \
258-
self.coord_exp[pos_vals], var_name, title, pop_name, buffer_deg, \
259-
extend, **kwargs)
260-
261218
@property
262219
def coord_exp(self):
263220
""" Return coord"""
@@ -270,3 +227,44 @@ def coord_exp(self, value):
270227
self._coord_exp = GridPoints(value)
271228
else:
272229
self._coord_exp = value
230+
231+
class ImpactFreqCurve():
232+
""" Impact exceedence frequency curve.
233+
234+
Attributes:
235+
return_per (np.array): return period
236+
impact (np.array): impact exceeding frequency
237+
unit (str): value unit used (given by exposures unit)
238+
label (str): string describing source data
239+
"""
240+
def __init__(self):
241+
self.return_per = np.array([])
242+
self.impact = np.array([])
243+
self.unit = ''
244+
self.label = ''
245+
246+
def plot(self):
247+
"""Plot impact frequency curve.
248+
249+
Returns:
250+
matplotlib.figure.Figure, [matplotlib.axes._subplots.AxesSubplot]
251+
"""
252+
graph = u_plot.Graph2D(self.label)
253+
graph.add_subplot('Return period (year)', 'Impact (%s)' % self.unit)
254+
graph.add_curve(self.return_per, self.impact, 'y')
255+
return graph.get_elems()
256+
257+
def plot_compare(self, ifc):
258+
"""Plot current and input impact frequency curves in a figure.
259+
260+
Returns:
261+
matplotlib.figure.Figure, [matplotlib.axes._subplots.AxesSubplot]
262+
"""
263+
if self.unit != ifc.unit:
264+
LOGGER.warning("Comparing between two different units: %s and %s",\
265+
self.unit, ifc.unit)
266+
graph = u_plot.Graph2D('', 2)
267+
graph.add_subplot('Return period (year)', 'Impact (%s)' % self.unit)
268+
graph.add_curve(self.return_per, self.impact, 'b', label=self.label)
269+
graph.add_curve(ifc.return_per, ifc.impact, 'r', label=ifc.label)
270+
return graph.get_elems()

0 commit comments

Comments
 (0)