Skip to content

Commit 6095358

Browse files
authored
Merge pull request #274 from samluethi/feature/impact_funcs
Feature/impact funcs
2 parents 59f6fd6 + ef360bf commit 6095358

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

climada/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '2.2.1-dev'
1+
__version__ = '3.0.0-cand'

climada/entity/impact_funcs/base.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,68 @@ def check(self):
143143
'origin of the intensity scale. In impact.calc '
144144
'the impact is always null at intensity = 0.')
145145

146+
def set_step_impf(self, intensity, mdd=(0, 1), paa=(1, 1), impf_id=1):
146147

148+
""" Step function type impact function.
149+
150+
By default, everything is destroyed above the step.
151+
Useful for high resolution modelling.
152+
153+
This method modifies self (climada.entity.impact_funcs instance)
154+
by assigning an id, intensity, mdd and paa to the impact function.
155+
156+
Parameters
157+
----------
158+
intensity: tuple(float, float, float)
159+
tuple of 3-intensity numbers: (minimum, threshold, maximum)
160+
mdd: tuple(float, float)
161+
(min, max) mdd values. The default is (0, 1)
162+
paa: tuple(float, float)
163+
(min, max) paa values. The default is (1, 1)
164+
impf_id : int, optional, default=1
165+
impact function id
166+
167+
"""
168+
169+
self.id = impf_id
170+
inten_min, threshold, inten_max = intensity
171+
self.intensity = np.array([inten_min, threshold, threshold, inten_max])
172+
paa_min, paa_max = paa
173+
self.paa = np.array([paa_min, paa_min, paa_max, paa_max])
174+
mdd_min, mdd_max = mdd
175+
self.mdd = np.array([mdd_min, mdd_min, mdd_max, mdd_max])
176+
177+
def set_sigmoid_impf(self, intensity, L, k, x0, if_id=1):
178+
179+
""" Sigmoid type impact function hinging on three parameter.
180+
181+
This type of impact function is very flexible for any sort of study,
182+
hazard and resolution. The sigmoid is defined as:
183+
184+
.. math::
185+
f(x) = \frac{L}{1+exp^{-k(x-x0)}}
186+
187+
For more information: https://en.wikipedia.org/wiki/Logistic_function
188+
189+
This method modifies self (climada.entity.impact_funcs instance)
190+
by assining an id, intensity, mdd and paa to the impact function.
191+
192+
Parameters
193+
----------
194+
intensity: tuple(float, float, float)
195+
tuple of 3 intensity numbers along np.arange(min, max, step)
196+
L : float
197+
"top" of sigmoid
198+
k : float
199+
"slope" of sigmoid
200+
x0 : float
201+
intensity value where f(x)==L/2
202+
if_id : int, optional, default=1
203+
impact function id
204+
205+
"""
206+
self.id = if_id
207+
inten_min, inten_max, inten_step = intensity
208+
self.intensity = np.arange(inten_min, inten_max, inten_step)
209+
self.paa = np.ones(len(self.intensity))
210+
self.mdd = L / (1 + np.exp(-k * (self.intensity - x0)))

climada/entity/impact_funcs/test/test_base.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,29 @@ def test_calc_mdr_pass(self):
3636
new_inten = 17.2
3737
self.assertEqual(imp_fun.calc_mdr(new_inten), 0.029583999999999996)
3838

39+
def test_set_step(self):
40+
"""Check default impact function: step function"""
41+
inten = (0, 5, 10)
42+
imp_fun = ImpactFunc()
43+
imp_fun.set_step_impf(inten)
44+
self.assertTrue(np.array_equal(imp_fun.paa, np.ones(4)))
45+
self.assertTrue(np.array_equal(imp_fun.mdd, np.array([0, 0, 1, 1])))
46+
self.assertTrue(np.array_equal(imp_fun.intensity, np.array([0, 5, 5, 10])))
47+
48+
def test_set_sigmoid(self):
49+
"""Check default impact function: sigmoid function"""
50+
inten = (0, 100, 5)
51+
imp_fun = ImpactFunc()
52+
imp_fun.set_sigmoid_impf(inten, L=1.0, k=2., x0=50.)
53+
self.assertTrue(np.array_equal(imp_fun.paa, np.ones(20)))
54+
self.assertEqual(imp_fun.mdd[10], 0.5)
55+
self.assertEqual(imp_fun.mdd[-1], 1.0)
56+
self.assertTrue(np.array_equal(imp_fun.intensity, np.arange(0, 100, 5)))
57+
3958
# Execute Tests
4059
if __name__ == "__main__":
4160
TESTS = unittest.TestLoader().loadTestsFromTestCase(TestInterpolation)
4261
unittest.TextTestRunner(verbosity=2).run(TESTS)
62+
63+
64+

0 commit comments

Comments
 (0)