@@ -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