Skip to content

Commit

Permalink
Feature/init unsequa (#573)
Browse files Browse the repository at this point in the history
Update inits and add type hinting in unsequa

Co-authored-by: Evelyn-M <evelyn.muehlhofer@usys.ethz.ch>
Co-authored-by: Thomas Vogt <thomas.vogt@pik-potsdam.de>
Co-authored-by: Chahan Kropf <chahan.kropf@posteo.com>
  • Loading branch information
4 people authored Nov 1, 2022
1 parent a30c044 commit 156c6fc
Show file tree
Hide file tree
Showing 6 changed files with 3,558 additions and 105 deletions.
22 changes: 17 additions & 5 deletions climada/engine/unsequa/calc_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,26 @@ class Calc():
Contains the generic sampling and sensitivity methods. For computing
the uncertainty distribution for specific CLIMADA outputs see
the subclass CalcImpact and CalcCostBenefit.
Attributes
----------
_input_var_names : tuple(str)
Names of the required uncertainty variables.
_metric_names : tuple(str)
Names of the output metrics.
"""

_input_var_names = ()
"""Names of the required uncertainty variables"""

_metric_names = ()
"""Names of the output metrics"""

def __init__(self):
"""
Empty constructor to be overwritten by subclasses
"""
self.input_var_names = ()
self.metric_names = ()
self.check_distr()
pass

def check_distr(self):
"""
Expand Down Expand Up @@ -92,7 +104,7 @@ def input_vars(self):
All uncertainty variables associated with the calculation
"""
return tuple(getattr(self, var) for var in self.input_var_names)
return tuple(getattr(self, var) for var in self._input_var_names)

@property
def distr_dict(self):
Expand Down Expand Up @@ -331,7 +343,7 @@ def sensitivity(self, unc_output, sensitivity_method = 'sobol',
salib_kwargs = method.analyze.__code__.co_varnames # obtain all kwargs of the salib method
X = unc_output.samples_df.to_numpy() if 'X' in salib_kwargs else None

for metric_name in self.metric_names:
for metric_name in self._metric_names:
unc_df = unc_output.get_unc_df(metric_name)
sens_df = _calc_sens_df(method, unc_output.problem_sa, sensitivity_kwargs,
unc_output.param_labels, X, unc_df)
Expand Down
49 changes: 35 additions & 14 deletions climada/engine/unsequa/calc_cost_benefit.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@

from functools import partial
import pandas as pd
from typing import Optional, Union

from climada.engine.cost_benefit import CostBenefit
from climada.engine.unsequa import Calc, InputVar, UncCostBenefitOutput
from climada.util import log_level
from climada.hazard import Hazard
from climada.entity import Entity

LOGGER = logging.getLogger(__name__)

Expand All @@ -45,15 +48,8 @@ class CalcCostBenefit(Calc):
Attributes
----------
metric_names : tuple(str)
Names of the cost benefit output metris
('tot_climate_risk', 'benefit', 'cost_ben_ratio',
'imp_meas_present', 'imp_meas_future')
value_unit : str
Unit of the exposures value
input_var_names : tuple(str)
Names of the required uncertainty variables
('haz_input_var', 'ent_input_var', 'haz_fut_input_var', 'ent_fut_input_var')
haz_input_var : climada.engine.uncertainty.input_var.InputVar
Present Hazard uncertainty variable
ent_input_var : climada.engine.uncertainty.input_var.InputVar
Expand All @@ -62,11 +58,40 @@ class CalcCostBenefit(Calc):
Future Hazard uncertainty variable
ent_fut_input_var : climada.engine.uncertainty.input_var.InputVar
Future Entity uncertainty variable
_input_var_names : tuple(str)
Names of the required uncertainty variables
('haz_input_var', 'ent_input_var', 'haz_fut_input_var', 'ent_fut_input_var')
_metric_names : tuple(str)
Names of the cost benefit output metrics
('tot_climate_risk', 'benefit', 'cost_ben_ratio',
'imp_meas_present', 'imp_meas_future')
"""

def __init__(self, haz_input_var, ent_input_var,
haz_fut_input_var=None, ent_fut_input_var=None):
_input_var_names = (
'haz_input_var',
'ent_input_var',
'haz_fut_input_var',
'ent_fut_input_var',
)
"""Names of the required uncertainty variables"""

_metric_names = (
'tot_climate_risk',
'benefit',
'cost_ben_ratio',
'imp_meas_present',
'imp_meas_future',
)
"""Names of the cost benefit output metrics"""

def __init__(
self,
haz_input_var: Union[InputVar, Hazard],
ent_input_var: Union[InputVar, Entity],
haz_fut_input_var: Optional[Union[InputVar, Hazard]] = None,
ent_fut_input_var: Optional[Union[InputVar, Entity]] = None,
):
"""Initialize UncCalcCostBenefit
Sets the uncertainty input variables, the cost benefit metric_names,
Expand Down Expand Up @@ -94,15 +119,11 @@ def __init__(self, haz_input_var, ent_input_var,
"""

Calc.__init__(self)
self.input_var_names = ('haz_input_var', 'ent_input_var',
'haz_fut_input_var', 'ent_fut_input_var')
self.haz_input_var = InputVar.var_to_inputvar(haz_input_var)
self.ent_input_var = InputVar.var_to_inputvar(ent_input_var)
self.haz_fut_input_var = InputVar.var_to_inputvar(haz_fut_input_var)
self.ent_fut_input_var = InputVar.var_to_inputvar(ent_fut_input_var)
self.metric_names = ('tot_climate_risk', 'benefit',
'cost_ben_ratio',
'imp_meas_present', 'imp_meas_future')

self.value_unit = self.ent_input_var.evaluate().exposures.value_unit
self.check_distr()

Expand Down
42 changes: 32 additions & 10 deletions climada/engine/unsequa/calc_impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@

import logging
import time
from typing import Union

import pandas as pd
import numpy as np

from climada.engine import ImpactCalc
from climada.engine.unsequa import Calc, InputVar, UncImpactOutput
from climada.entity import Exposures, ImpactFuncSet
from climada.hazard import Hazard
from climada.util import log_level

LOGGER = logging.getLogger(__name__)
Expand All @@ -49,23 +52,44 @@ class CalcImpact(Calc):
Compute eai_exp or not
calc_at_event : bool
Compute eai_exp or not
metric_names : tuple(str)
Names of the impact output metris
('aai_agg', 'freq_curve', 'at_event', 'eai_exp', 'tot_value')
value_unit : str
Unit of the exposures value
input_var_names : tuple(str)
Names of the required uncertainty input variables
('exp_input_var', 'impf_input_var', 'haz_input_var')
exp_input_var : climada.engine.uncertainty.input_var.InputVar
Exposure uncertainty variable
impf_input_var : climada.engine.uncertainty.input_var.InputVar
Impact function set uncertainty variable
haz_input_var: climada.engine.uncertainty.input_var.InputVar
Hazard uncertainty variable
_input_var_names : tuple(str)
Names of the required uncertainty input variables
('exp_input_var', 'impf_input_var', 'haz_input_var')
_metric_names : tuple(str)
Names of the impact output metrics
('aai_agg', 'freq_curve', 'at_event', 'eai_exp', 'tot_value')
"""

def __init__(self, exp_input_var, impf_input_var, haz_input_var):
_input_var_names = (
'exp_input_var',
'impf_input_var',
'haz_input_var',
)
"""Names of the required uncertainty variables"""

_metric_names = (
'aai_agg',
'freq_curve',
'at_event',
'eai_exp',
'tot_value',
)
"""Names of the cost benefit output metrics"""

def __init__(
self,
exp_input_var: Union[InputVar, Exposures],
impf_input_var: Union[InputVar, ImpactFuncSet],
haz_input_var: Union[InputVar, Hazard],
):
"""Initialize UncCalcImpact
Sets the uncertainty input variables, the impact metric_names, and the
Expand All @@ -83,12 +107,10 @@ def __init__(self, exp_input_var, impf_input_var, haz_input_var):
"""

Calc.__init__(self)
self.input_var_names = ('exp_input_var', 'impf_input_var', 'haz_input_var')
self.exp_input_var = InputVar.var_to_inputvar(exp_input_var)
self.impf_input_var = InputVar.var_to_inputvar(impf_input_var)
self.haz_input_var = InputVar.var_to_inputvar(haz_input_var)
self.metric_names = ('aai_agg', 'freq_curve', 'at_event',
'eai_exp', 'tot_value')

self.value_unit = self.exp_input_var.evaluate().value_unit
self.check_distr()

Expand Down
9 changes: 7 additions & 2 deletions climada/engine/unsequa/input_var.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from functools import partial
from itertools import zip_longest
import logging
from typing import Dict

import scipy as sp
import numpy as np
Expand Down Expand Up @@ -103,7 +104,11 @@ def imp_fun_tc(G, v_half, vmin, k, _id=1):
"""

def __init__(self, func, distr_dict):
def __init__(
self,
func: callable,
distr_dict: Dict,
):
"""
Initialize InputVar
Expand Down Expand Up @@ -133,7 +138,7 @@ def evaluate(self, **params):
Parameters
----------
**params : optional
Input parameters will be passed to self.InputVar_func.
Input parameters will be passed to self.func.
Returns
-------
Expand Down
12 changes: 6 additions & 6 deletions climada/engine/unsequa/test/test_unsequa.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,11 @@ def test_init_pass(self):
unc_calc = CalcImpact(exp_iv, impf_iv, haz_iv)

self.assertTupleEqual(
unc_calc.input_var_names,
unc_calc._input_var_names,
('exp_input_var', 'impf_input_var', 'haz_input_var')
)
self.assertTupleEqual(
unc_calc.metric_names,
unc_calc._metric_names,
('aai_agg', 'freq_curve', 'at_event', 'eai_exp', 'tot_value')
)
self.assertEqual(unc_calc.value_unit, exp_iv.evaluate().value_unit)
Expand Down Expand Up @@ -578,12 +578,12 @@ def test_init_pass(self):
unc_calc = CalcCostBenefit(haz_iv, ent_iv)

self.assertTupleEqual(
unc_calc.input_var_names,
unc_calc._input_var_names,
('haz_input_var', 'ent_input_var',
'haz_fut_input_var', 'ent_fut_input_var')
)
self.assertTupleEqual(
unc_calc.metric_names,
unc_calc._metric_names,
('tot_climate_risk', 'benefit', 'cost_ben_ratio',
'imp_meas_present', 'imp_meas_future')
)
Expand All @@ -602,12 +602,12 @@ def test_init_pass(self):
unc_calc = CalcCostBenefit(haz_iv, ent_iv, haz_iv, ent_fut_iv)

self.assertTupleEqual(
unc_calc.input_var_names,
unc_calc._input_var_names,
('haz_input_var', 'ent_input_var',
'haz_fut_input_var', 'ent_fut_input_var')
)
self.assertTupleEqual(
unc_calc.metric_names,
unc_calc._metric_names,
('tot_climate_risk', 'benefit', 'cost_ben_ratio',
'imp_meas_present', 'imp_meas_future')
)
Expand Down
3,529 changes: 3,461 additions & 68 deletions doc/tutorial/climada_engine_unsequa.ipynb

Large diffs are not rendered by default.

0 comments on commit 156c6fc

Please sign in to comment.