Skip to content

Commit b75ab91

Browse files
committed
refactor: adds consistency between attribute
1 parent b7bf68b commit b75ab91

1 file changed

Lines changed: 163 additions & 22 deletions

File tree

climada/trajectories/riskperiod.py

Lines changed: 163 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -66,42 +66,163 @@ def __init__(
6666
risk_transf_attach: float | None = None,
6767
risk_transf_cover: float | None = None,
6868
calc_residual: bool = False,
69-
measure: Measure | None = None,
7069
):
71-
self.snapshot0 = snapshot0
72-
self.snapshot1 = snapshot1
70+
self._snapshot0 = snapshot0
71+
self._snapshot1 = snapshot1
7372
self.date_idx = pd.date_range(
7473
snapshot0.date,
7574
snapshot1.date,
7675
periods=time_points,
7776
freq=interval_freq, # type: ignore
7877
name="date",
7978
)
80-
self.time_points = len(self.date_idx)
81-
self.interval_freq = pd.infer_freq(self.date_idx)
82-
self.measure = measure
83-
self._prop_H1 = np.linspace(0, 1, num=self.time_points)
84-
self._prop_H0 = 1 - self._prop_H1
8579
self.interpolation_strategy = interpolation_strategy or LinearInterpolation()
8680
self.impact_computation_strategy = (
8781
impact_computation_strategy or ImpactCalcComputation()
8882
)
89-
self._E0H0, self._E1H0, self._E0H1, self._E1H1 = (
90-
self.impact_computation_strategy.compute_impacts(
91-
snapshot0,
92-
snapshot1,
93-
risk_transf_attach,
94-
risk_transf_cover,
95-
calc_residual,
96-
)
97-
)
83+
self.risk_transf_attach = risk_transf_attach
84+
self.risk_transf_cover = risk_transf_cover
85+
self.calc_residual = calc_residual
86+
self.measure = None # Only possible to set with apply_measure to make sure snapshots are consistent
87+
88+
self._group_id_E0 = self.snapshot0.exposure.gdf["group_id"].values
89+
self._group_id_E1 = self.snapshot1.exposure.gdf["group_id"].values
90+
91+
def _reset_impact_data(self):
92+
self._impacts_arrays = None, None, None, None
9893
self._imp_mats_H0, self._imp_mats_H1 = None, None
9994
self._imp_mats_E0, self._imp_mats_E1 = None, None
10095
self._per_date_eai_H0, self._per_date_eai_H1 = None, None
10196
self._per_date_aai_H0, self._per_date_aai_H1 = None, None
10297
self._per_date_return_periods_H0, self._per_date_return_periods_H1 = None, None
103-
self._group_id_E0 = self.snapshot0.exposure.gdf["group_id"].values
104-
self._group_id_E1 = self.snapshot1.exposure.gdf["group_id"].values
98+
99+
@property
100+
def snapshot0(self):
101+
return self._snapshot0
102+
103+
@property
104+
def snapshot1(self):
105+
return self._snapshot1
106+
107+
@property
108+
def date_idx(self):
109+
return self._date_idx
110+
111+
@date_idx.setter
112+
def date_idx(self, value, /):
113+
if not isinstance(value, pd.DatetimeIndex):
114+
raise ValueError("Not a DatetimeIndex")
115+
116+
self._date_idx = value
117+
self._time_points = len(self.date_idx)
118+
self._interval_freq = pd.infer_freq(self.date_idx)
119+
self._prop_H1 = np.linspace(0, 1, num=self.time_points)
120+
self._prop_H0 = 1 - self._prop_H1
121+
self._reset_impact_data()
122+
123+
@property
124+
def time_points(self):
125+
return self._time_points
126+
127+
@time_points.setter
128+
def time_points(self, value, /):
129+
if not isinstance(value, int):
130+
raise ValueError("Not an int")
131+
132+
self.date_idx = pd.date_range(
133+
self.snapshot0.date, self.snapshot1.date, periods=value, name="date"
134+
)
135+
136+
@property
137+
def interval_freq(self):
138+
return self._interval_freq
139+
140+
@interval_freq.setter
141+
def interval_freq(self, value, /):
142+
freq = pd.tseries.frequencies.to_offset(value)
143+
self.date_idx = pd.date_range(
144+
self.snapshot0.date, self.snapshot1.date, freq=freq, name="date"
145+
)
146+
147+
@property
148+
def interpolation_strategy(self):
149+
return self._interpolation_strategy
150+
151+
@interpolation_strategy.setter
152+
def interpolation_strategy(self, value, /):
153+
if not isinstance(value, InterpolationStrategy):
154+
raise ValueError("Not an interpolation strategy")
155+
156+
self._interpolation_strategy = value
157+
self._reset_impact_data()
158+
159+
@property
160+
def impact_computation_strategy(self):
161+
return self._impact_computation_strategy
162+
163+
@impact_computation_strategy.setter
164+
def impact_computation_strategy(self, value, /):
165+
if not isinstance(value, ImpactComputationStrategy):
166+
raise ValueError("Not an interpolation strategy")
167+
168+
self._impact_computation_strategy = value
169+
self._reset_impact_data()
170+
171+
@lazy_property
172+
def impacts_arrays(self):
173+
return self.impact_computation_strategy.compute_impacts(
174+
self.snapshot0,
175+
self.snapshot1,
176+
self.risk_transf_attach,
177+
self.risk_transf_cover,
178+
self.calc_residual,
179+
)
180+
181+
@property
182+
def _E0H0(self):
183+
return self.impacts_arrays[0]
184+
185+
@property
186+
def _E1H0(self):
187+
return self.impacts_arrays[1]
188+
189+
@property
190+
def _E0H1(self):
191+
return self.impacts_arrays[2]
192+
193+
@property
194+
def _E1H1(self):
195+
return self.impacts_arrays[3]
196+
197+
@property
198+
def risk_transf_attach(self):
199+
return self._risk_transfer_attach
200+
201+
@risk_transf_attach.setter
202+
def risk_transf_attach(self, value, /):
203+
self._risk_transfer_attach = value
204+
self._reset_impact_data()
205+
206+
@property
207+
def risk_transf_cover(self):
208+
return self._risk_transfer_cover
209+
210+
@risk_transf_cover.setter
211+
def risk_transf_cover(self, value, /):
212+
self._risk_transfer_cover = value
213+
self._reset_impact_data()
214+
215+
@property
216+
def calc_residual(self):
217+
return self._calc_residual
218+
219+
@calc_residual.setter
220+
def calc_residual(self, value, /):
221+
if not isinstance(value, bool):
222+
raise ValueError("Not a boolean")
223+
224+
self._calc_residual = value
225+
self._reset_impact_data()
105226

106227
@lazy_property
107228
def imp_mats_H0(self):
@@ -336,9 +457,10 @@ def calc_aai_per_group_metric(self):
336457
return aai_per_group_df
337458

338459
def calc_return_periods_metric(self, return_periods):
339-
rp_0, rp_1 = self.per_date_return_periods_H0(
340-
return_periods
341-
), self.per_date_return_periods_H1(return_periods)
460+
rp_0, rp_1 = (
461+
self.per_date_return_periods_H0(return_periods),
462+
self.per_date_return_periods_H1(return_periods),
463+
)
342464
per_date_rp = np.multiply(self._prop_H0.reshape(-1, 1), rp_0) + np.multiply(
343465
self._prop_H1.reshape(-1, 1), rp_1
344466
)
@@ -375,3 +497,22 @@ def calc_risk_components_metric(self):
375497
df["group"] = pd.NA
376498
df["measure"] = self.measure.name if self.measure else "no_measure"
377499
return df
500+
501+
def apply_measure(self, measure: Measure):
502+
snap0 = self.snapshot0.apply_measure(measure)
503+
snap1 = self.snapshot1.apply_measure(measure)
504+
505+
risk_period = CalcRiskPeriod(
506+
snap0,
507+
snap1,
508+
self.interval_freq,
509+
self.time_points,
510+
self.interpolation_strategy,
511+
self.impact_computation_strategy,
512+
self.risk_transf_attach,
513+
self.risk_transf_cover,
514+
self.calc_residual,
515+
)
516+
517+
risk_period.measure = measure
518+
return risk_period

0 commit comments

Comments
 (0)