Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0a47b9c
Set init, uncertainty, and _compute_metrics as abstract methods
luseverin Apr 7, 2025
42c0e6f
Set UncOutput init as abstract
luseverin Apr 7, 2025
e200f3e
Copy calc_impact to adapt it to cascade
luseverin Apr 7, 2025
623dc85
First draft of rewritting map_calc
luseverin Apr 7, 2025
8121416
Copy functions to do the network impact calc and correct some imports
luseverin Apr 7, 2025
7e650c3
Update input args of compute_imp_metrics
luseverin Apr 8, 2025
d67ed7b
Add extension of UncOutput for cascade
luseverin Apr 8, 2025
5b42eba
Continue updating uncertainty function for cascade
luseverin Apr 8, 2025
80ebe63
Call to correct UncOutput
luseverin Apr 8, 2025
f8b734f
Some changes to cascade specific functions
luseverin Apr 8, 2025
a15fba9
Add class names
luseverin Apr 9, 2025
cd2c8d4
Add class import to __init__
luseverin Apr 9, 2025
0009703
Correct method names to comply with abstract class
luseverin Apr 9, 2025
e29e703
hardcode value_unit
luseverin Apr 9, 2025
6906784
Change occurence of exp_input_var to nw_input_var
luseverin Apr 9, 2025
68f01c7
Define base UncOutput class
luseverin Apr 9, 2025
1f523e1
Rename _compute_metrics wrapper
luseverin May 13, 2025
7f78263
Deabstract __init__ method to allow subclass init with super()
luseverin May 13, 2025
5a538ea
Update Hazard().apply_climate_scenario_knu in tutorials
luseverin May 13, 2025
da3f690
Update use of order_samples in tuto
luseverin May 13, 2025
08671e4
Update name of _compute_metrics method in delta_climate and cost_benefit
luseverin May 13, 2025
d5c129c
Remove UncBaseOutput subclass as __init__ is no longer abstract
luseverin May 13, 2025
1b47887
Finish updating draft of unsequa cascade
luseverin May 13, 2025
7c616ed
Remove cascade unsequa from branch
luseverin May 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion climada/engine/unsequa/calc_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import datetime as dt
import itertools
import logging
from abc import ABC, abstractmethod

import numpy as np
import pandas as pd
Expand All @@ -33,7 +34,7 @@
LOGGER = logging.getLogger(__name__)


class Calc:
class Calc(ABC):
"""
Base class for uncertainty quantification

Expand Down Expand Up @@ -80,6 +81,7 @@
_metric_names = ()
"""Names of the output metrics"""

@abstractmethod
def __init__(self):
"""
Empty constructor to be overwritten by subclasses
Expand Down Expand Up @@ -423,6 +425,16 @@

return sens_output

@abstractmethod
def uncertainty(self):
"""Compute the uncertainty of the output values"""
pass

Check warning on line 431 in climada/engine/unsequa/calc_base.py

View check run for this annotation

Jenkins - WCR / Pylint

unnecessary-pass

NORMAL: Unnecessary pass statement
Raw output
Used when a "pass" statement that can be avoided is encountered.

Check warning on line 431 in climada/engine/unsequa/calc_base.py

View check run for this annotation

Jenkins - WCR / Code Coverage

Not covered line

Line 431 is not covered by tests

@abstractmethod
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private and abstract seems somehow contradicting. if we go for it, compute_metrics ought to be public.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree. An abstract method just means that "this implementation is to be defined in a derived class". Depending on the semantics of the class, the method in question may very well be private.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peanutfun Technically speaking, you're absolutely right. In this particular case I still think compute_metrics ought to be public.

def _compute_metrics(self):
"""Compute the uncertainty of the output values"""
pass

Check warning on line 436 in climada/engine/unsequa/calc_base.py

View check run for this annotation

Jenkins - WCR / Pylint

unnecessary-pass

NORMAL: Unnecessary pass statement
Raw output
Used when a "pass" statement that can be avoided is encountered.

Check warning on line 436 in climada/engine/unsequa/calc_base.py

View check run for this annotation

Jenkins - WCR / Code Coverage

Not covered line

Line 436 is not covered by tests


def _multiprocess_chunksize(samples_df, processes):
"""Divides the samples into chunks for multiprocesses computing
Expand Down
12 changes: 3 additions & 9 deletions climada/engine/unsequa/calc_cost_benefit.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
self.value_unit = self.ent_input_var.evaluate().exposures.value_unit
self.check_distr()

def uncertainty(

Check warning on line 142 in climada/engine/unsequa/calc_cost_benefit.py

View check run for this annotation

Jenkins - WCR / Pylint

arguments-differ

NORMAL: Number of parameters was 1 in 'Calc.uncertainty' and is now 5 in overriding 'CalcCostBenefit.uncertainty' method
Raw output
Used when a method has a different number of arguments than in the implementedinterface or in an overridden method.
self, unc_sample, processes=1, chunksize=None, **cost_benefit_kwargs
):
"""
Expand Down Expand Up @@ -218,9 +218,7 @@

one_sample = samples_df.iloc[0:1]
start = time.time()
self._compute_cb_metrics(
one_sample, cost_benefit_kwargs, chunksize=1, processes=1
)
self._compute_metrics(one_sample, cost_benefit_kwargs, chunksize=1, processes=1)
elapsed_time = time.time() - start
self.est_comp_time(unc_sample.n_samples, elapsed_time, processes)

Expand All @@ -231,9 +229,7 @@
tot_climate_risk,
benefit,
cost_ben_ratio,
] = self._compute_cb_metrics(
samples_df, cost_benefit_kwargs, chunksize, processes
)
] = self._compute_metrics(samples_df, cost_benefit_kwargs, chunksize, processes)

# Assign computed impact distribution data to self
tot_climate_risk_unc_df = pd.DataFrame(
Expand Down Expand Up @@ -293,9 +289,7 @@
cost_benefit_kwargs=cost_benefit_kwargs,
)

def _compute_cb_metrics(
self, samples_df, cost_benefit_kwargs, chunksize, processes
):
def _compute_metrics(self, samples_df, cost_benefit_kwargs, chunksize, processes):

Check warning on line 292 in climada/engine/unsequa/calc_cost_benefit.py

View check run for this annotation

Jenkins - WCR / Pylint

arguments-differ

NORMAL: Number of parameters was 1 in 'Calc._compute_metrics' and is now 5 in overriding 'CalcCostBenefit._compute_metrics' method
Raw output
Used when a method has a different number of arguments than in the implementedinterface or in an overridden method.
"""Compute the uncertainty metrics

Parameters
Expand Down
8 changes: 3 additions & 5 deletions climada/engine/unsequa/calc_delta_climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
self.value_unit = self.exp_initial_input_var.evaluate().value_unit
self.check_distr()

def uncertainty(

Check warning on line 153 in climada/engine/unsequa/calc_delta_climate.py

View check run for this annotation

Jenkins - WCR / Pylint

arguments-differ

NORMAL: Number of parameters was 1 in 'Calc.uncertainty' and is now 8 in overriding 'CalcDeltaImpact.uncertainty' method
Raw output
Used when a method has a different number of arguments than in the implementedinterface or in an overridden method.
self,
unc_sample,
rp=None,
Expand Down Expand Up @@ -258,7 +258,7 @@

one_sample = samples_df.iloc[0:1]
start = time.time()
self._compute_imp_metrics(one_sample, chunksize=1, processes=1)
self._compute_metrics(one_sample, chunksize=1, processes=1)
elapsed_time = time.time() - start
self.est_comp_time(unc_sample.n_samples, elapsed_time, processes)

Expand All @@ -267,9 +267,7 @@
freq_curve_list,
eai_exp_list,
at_event_list,
] = self._compute_imp_metrics(
samples_df, chunksize=chunksize, processes=processes
)
] = self._compute_metrics(samples_df, chunksize=chunksize, processes=processes)

# Assign computed impact distribution data to self
aai_agg_unc_df = pd.DataFrame(aai_agg_list, columns=["aai_agg"])
Expand All @@ -295,7 +293,7 @@
coord_df=coord_df,
)

def _compute_imp_metrics(self, samples_df, chunksize, processes):
def _compute_metrics(self, samples_df, chunksize, processes):

Check warning on line 296 in climada/engine/unsequa/calc_delta_climate.py

View check run for this annotation

Jenkins - WCR / Pylint

arguments-differ

NORMAL: Number of parameters was 1 in 'Calc._compute_metrics' and is now 4 in overriding 'CalcDeltaImpact._compute_metrics' method
Raw output
Used when a method has a different number of arguments than in the implementedinterface or in an overridden method.
"""Compute the uncertainty metrics

Parameters
Expand Down Expand Up @@ -428,7 +426,7 @@
at_event_final = np.array([])

if relative_delta:
delta_func = lambda x, y: safe_divide(x - y, y)

Check warning on line 429 in climada/engine/unsequa/calc_delta_climate.py

View check run for this annotation

Jenkins - WCR / Pylint

unnecessary-lambda-assignment

LOW: Lambda expression assigned to a variable. Define a function using the "def" keyword instead.
Raw output
no description found
else:
delta_func = lambda x, y: x - y

Expand Down
8 changes: 3 additions & 5 deletions climada/engine/unsequa/calc_impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
self.value_unit = self.exp_input_var.evaluate().value_unit
self.check_distr()

def uncertainty(

Check warning on line 124 in climada/engine/unsequa/calc_impact.py

View check run for this annotation

Jenkins - WCR / Pylint

arguments-differ

NORMAL: Number of parameters was 1 in 'Calc.uncertainty' and is now 7 in overriding 'CalcImpact.uncertainty' method
Raw output
Used when a method has a different number of arguments than in the implementedinterface or in an overridden method.
self,
unc_sample,
rp=None,
Expand Down Expand Up @@ -219,14 +219,12 @@

one_sample = samples_df.iloc[0:1]
start = time.time()
self._compute_imp_metrics(one_sample, chunksize=1, processes=1)
self._compute_metrics(one_sample, chunksize=1, processes=1)
elapsed_time = time.time() - start
self.est_comp_time(unc_sample.n_samples, elapsed_time, processes)

[aai_agg_list, freq_curve_list, eai_exp_list, at_event_list] = (
self._compute_imp_metrics(
samples_df, chunksize=chunksize, processes=processes
)
self._compute_metrics(samples_df, chunksize=chunksize, processes=processes)
)

# Assign computed impact distribution data to self
Expand Down Expand Up @@ -256,7 +254,7 @@
coord_df=coord_df,
)

def _compute_imp_metrics(self, samples_df, chunksize, processes):
def _compute_metrics(self, samples_df, chunksize, processes):

Check warning on line 257 in climada/engine/unsequa/calc_impact.py

View check run for this annotation

Jenkins - WCR / Pylint

arguments-differ

NORMAL: Number of parameters was 1 in 'Calc._compute_metrics' and is now 4 in overriding 'CalcImpact._compute_metrics' method
Raw output
Used when a method has a different number of arguments than in the implementedinterface or in an overridden method.
"""Compute the uncertainty metrics

Parameters
Expand Down
65 changes: 61 additions & 4 deletions climada/engine/unsequa/unc_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import datetime as dt
import logging
from abc import ABC, abstractmethod

Check warning on line 31 in climada/engine/unsequa/unc_output.py

View check run for this annotation

Jenkins - WCR / Pylint

unused-import

NORMAL: Unused abstractmethod imported from abc
Raw output
Used when an imported module or variable is not used.
from itertools import zip_longest
from pathlib import Path

Expand Down Expand Up @@ -71,7 +72,7 @@
}


class UncOutput:
class UncOutput(ABC):

Check warning on line 75 in climada/engine/unsequa/unc_output.py

View check run for this annotation

Jenkins - WCR / Pylint

too-many-public-methods

LOW: Too many public methods (25/20)
Raw output
Used when class has too many public methods, try to reduce this to get asimpler (and so easier to use) class.
"""
Class to store and plot uncertainty and sensitivity analysis output data

Expand Down Expand Up @@ -107,16 +108,20 @@
"sensitivity_kwargs",
]

# @abstractmethod
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making __init__ abstract looks beyond the target to me. Is there a use case?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. You usually call inits of base classes from derived classes instead of overriding them.

def __init__(self, samples_df, unit=None):
# """
# Empty constructor to be overwritten by subclasses
# """
"""
Initialize Uncertainty Data object.
Initialize Uncertainty Data object

Parameters
----------
samples_df : pandas.DataFrame
input parameters samples
input parameters samples
unit : str, optional
value unit
value unit
"""
# Data
self.samples_df = samples_df
Expand Down Expand Up @@ -1232,6 +1237,58 @@
return unc_data


# class UncBaseOutput(UncOutput):
# """
# Class to store and plot uncertainty and sensitivity analysis output data
#
# This is the base class to store uncertainty and sensitivity outputs of an
# analysis done on climada.engine.impact.Impact() or
# climada.engine.costbenefit.CostBenefit() object.
#
# Attributes
# ----------
# samples_df : pandas.DataFrame
# Values of the sampled uncertainty parameters. It has n_samples rows
# and one column per uncertainty parameter.
# sampling_method : str
# Name of the sampling method from SAlib.
# https://salib.readthedocs.io/en/latest/api.html#
# n_samples : int
# Effective number of samples (number of rows of samples_df)
# param_labels : list
# Name of all the uncertainty parameters
# distr_dict : dict
# Comon flattened dictionary of all the distr_dict of all input variables.
# It represents the distribution of all the uncertainty parameters.
# problem_sa : dict
# The description of the uncertainty variables and their
# distribution as used in SALib.
# https://salib.readthedocs.io/en/latest/basics.html.
# """
#
# _metadata = [
# "sampling_method",
# "sampling_kwargs",
# "sensitivity_method",
# "sensitivity_kwargs",
# ]
#
# def __init__(self, samples_df, unit=None):
# """
# Initialize Uncertainty Data object.
#
# Parameters
# ----------
# samples_df : pandas.DataFrame
# input parameters samples
# unit : str, optional
# value unit
# """
# # Data
# self.samples_df = samples_df
# self.unit = unit


class UncImpactOutput(UncOutput):
"""Extension of UncOutput specific for CalcImpact, returned by the
uncertainty() method.
Expand Down
2,660 changes: 2,182 additions & 478 deletions doc/tutorial/climada_engine_unsequa.ipynb

Large diffs are not rendered by default.

Loading