@@ -555,7 +555,39 @@ def impact_computation_strategy(self, value, /):
555555 self ._impact_computation_strategy = value
556556 self ._reset_impact_data ()
557557
558- ##### Impact objects cube / Risk Cube #####
558+ def apply_measure (self , measure : Measure ) -> "CalcRiskMetricsPeriod" :
559+ """Creates a new `CalcRiskMetricsPeriod` object with a measure.
560+
561+ The given measure is applied to both snapshot of the risk period.
562+
563+ Parameters
564+ ----------
565+ measure : Measure
566+ The measure to apply.
567+
568+ Returns
569+ -------
570+
571+ CalcRiskPeriod
572+ The risk period with given measure applied.
573+
574+ """
575+ snap0 = self .snapshot_start .apply_measure (measure )
576+ snap1 = self .snapshot_end .apply_measure (measure )
577+
578+ risk_period = CalcRiskMetricsPeriod (
579+ snap0 ,
580+ snap1 ,
581+ self .time_resolution ,
582+ self .interpolation_strategy ,
583+ self .impact_computation_strategy ,
584+ )
585+
586+ risk_period .measure = measure
587+ return risk_period
588+
589+ ###################################################
590+ ##### Impact objects cube / Risk Cube corners #####
559591
560592 @lazy_property
561593 def E0H0V0 (self ) -> Impact :
@@ -631,7 +663,8 @@ def E1H1V1(self) -> Impact:
631663
632664 ###############################
633665
634- ### Impact Matrices arrays ####
666+ #################################################
667+ ### Impact Matrices arrays / Risk Cube edges ####
635668
636669 def _interp_mats (self , start_attr , end_attr ) -> list :
637670 """Helper to reduce repetition in impact matrix interpolation."""
@@ -661,23 +694,26 @@ def imp_mats_H1V1(self) -> list:
661694 """List of `time_points` impact matrices with changing exposure, future hazard and future vulnerability."""
662695 return self ._interp_mats ("E0H1V1" , "E1H1V1" )
663696
697+ ### The following are for risk contributions
698+
664699 @property
665700 def imp_mats_E0H0V0 (self ) -> list :
666701 """List of `time_points` impact matrices with base exposure, base hazard and base vulnerability."""
667- return self ._interp_mats ( " E0H0V0" , "E0H0V0" )
702+ return [ self .E0H0V0 . imp_mat ] * self . time_points
668703
669704 @property
670705 def imp_mats_E0H1V0 (self ) -> list :
671706 """List of `time_points` impact matrices with base exposure, future hazard and base vulnerability."""
672- return self ._interp_mats ( " E0H1V0" , "E0H1V0" )
707+ return [ self .E0H1V0 . imp_mat ] * self . time_points
673708
674709 @property
675710 def imp_mats_E0H0V1 (self ) -> list :
676711 """List of `time_points` impact matrices with base exposure, base hazard and base vulnerability."""
677- return self ._interp_mats ( " E0H0V1" , "E0H0V1" )
712+ return [ self .E0H0V1 . imp_mat ] * self . time_points
678713
679714 ###############################
680715
716+ ###############################
681717 ########## Core EAI ###########
682718
683719 @property
@@ -729,10 +765,12 @@ def per_date_eai_E0H0V1(self) -> np.ndarray:
729765 self .imp_mats_E0H0V1 , self .snapshot_start .hazard .frequency
730766 )
731767
732- ##################################
733-
768+ ##############################
734769 ######### Core AAIs ##########
735770
771+ # Not required for final AAIs computation (we use final EAIs instead),
772+ # but could be useful in the future?
773+
736774 @property
737775 def per_date_aai_H0V0 (self ) -> np .ndarray :
738776 """Average annual impacts for changing exposure, starting hazard and starting vulnerability."""
@@ -768,8 +806,7 @@ def per_date_aai_E0H0V1(self) -> np.ndarray:
768806 """Average annual impacts for base exposure, base hazard and base vulnerability."""
769807 return calc_per_date_aais (self .per_date_eai_E0H0V1 )
770808
771- #################################
772-
809+ #############################
773810 ######### Core RPs #########
774811
775812 def per_date_return_periods_H0V0 (self , return_periods : list [int ]) -> np .ndarray :
@@ -809,8 +846,9 @@ def per_date_return_periods_H1V1(self, return_periods: list[int]) -> np.ndarray:
809846 )
810847
811848 ##################################
849+ ##### Interpolation of metrics ###
812850
813- ##### Interpolation of metrics #####
851+ # Actual results
814852
815853 def calc_eai (self ) -> np .ndarray :
816854 """Compute the EAIs at each date of the risk period (including changes in exposure, hazard and vulnerability)."""
@@ -843,8 +881,10 @@ def per_date_aai(self) -> np.ndarray:
843881 """Average annual impacts per date with changing exposure, changing hazard and changing vulnerability."""
844882 return calc_per_date_aais (self .per_date_eai )
845883
846- @lazy_property
847- def eai_gdf (self ) -> pd .DataFrame :
884+ ####################################
885+ ######## Tidying results ###########
886+
887+ def calc_eai_gdf (self ) -> pd .DataFrame :
848888 """Convenience function returning a DataFrame (with both datetime and coordinates ids) from `per_date_eai`.
849889
850890 This dataframe can easily be merged with one of the snapshot exposure geodataframe.
@@ -855,19 +895,6 @@ def eai_gdf(self) -> pd.DataFrame:
855895 The DataFrame from the starting snapshot is used as a basis (notably for `value` and `group_id`).
856896
857897 """
858- return self .calc_eai_gdf ()
859-
860- ####################################
861-
862- ### Metrics from impact matrices ###
863-
864- # These methods might go in a utils file instead, to be reused
865- # for a no interpolation case (and maybe the timeseries?)
866-
867- ####################################
868-
869- def calc_eai_gdf (self ) -> pd .DataFrame :
870- """Merge the per date EAIs of the risk period with the GeoDataframe of the exposure of the starting snapshot."""
871898 df = pd .DataFrame (self .per_date_eai , index = self .date_idx )
872899 df = df .reset_index ().melt (
873900 id_vars = DEFAULT_PERIOD_INDEX_NAME ,
@@ -924,7 +951,8 @@ def calc_aai_per_group_metric(self) -> pd.DataFrame | None:
924951 )
925952 return None
926953
927- eai_pres_groups = self .eai_gdf [
954+ eai_gdf = self .calc_eai_gdf ()
955+ eai_pres_groups = eai_gdf [
928956 [
929957 DEFAULT_PERIOD_INDEX_NAME ,
930958 COORD_ID_COL_NAME ,
@@ -939,7 +967,7 @@ def calc_aai_per_group_metric(self) -> pd.DataFrame | None:
939967 LOGGER .warning (
940968 "Group id are changing between present and future snapshot. Per group AAI will be linearly interpolated."
941969 )
942- eai_fut_groups = self . eai_gdf .copy ()
970+ eai_fut_groups = eai_gdf .copy ()
943971 eai_fut_groups [GROUP_COL_NAME ] = pd .Categorical (
944972 np .tile (self ._group_id_E1 , len (self .date_idx )),
945973 categories = self ._groups_id ,
@@ -1009,24 +1037,24 @@ def calc_risk_contributions_metric(self) -> pd.DataFrame:
10091037 hazard and vulnerability).
10101038
10111039 """
1012- per_date_aai_E0V0 = self .interpolation_strategy .interp_over_hazard_dim (
1040+ aai_changes_hazard_only = self .interpolation_strategy .interp_over_hazard_dim (
10131041 self .per_date_aai_E0H0V0 , self .per_date_aai_E0H1V0
10141042 )
1015- per_date_aai_E0H0 = self .interpolation_strategy .interp_over_vulnerability_dim (
1016- self .per_date_aai_E0H0V0 , self .per_date_aai_E0H0V1
1043+ aai_changes_vulnerability_only = (
1044+ self .interpolation_strategy .interp_over_vulnerability_dim (
1045+ self .per_date_aai_E0H0V0 , self .per_date_aai_E0H0V1
1046+ )
10171047 )
10181048 df = pd .DataFrame (
10191049 {
10201050 CONTRIBUTION_TOTAL_RISK_NAME : self .per_date_aai ,
10211051 CONTRIBUTION_BASE_RISK_NAME : self .per_date_aai [0 ],
10221052 CONTRIBUTION_EXPOSURE_NAME : self .per_date_aai_H0V0
10231053 - self .per_date_aai [0 ],
1024- CONTRIBUTION_HAZARD_NAME : per_date_aai_E0V0
1025- # - (self.per_date_aai_H0V0 - self.per_date_aai[0])
1054+ CONTRIBUTION_HAZARD_NAME : aai_changes_hazard_only
10261055 - self .per_date_aai [0 ],
1027- CONTRIBUTION_VULNERABILITY_NAME : per_date_aai_E0H0
1056+ CONTRIBUTION_VULNERABILITY_NAME : aai_changes_vulnerability_only
10281057 - self .per_date_aai [0 ],
1029- # - (self.per_date_aai_H0V0 - self.per_date_aai[0]),
10301058 },
10311059 index = self .date_idx ,
10321060 )
@@ -1056,36 +1084,9 @@ def calc_risk_contributions_metric(self) -> pd.DataFrame:
10561084 df [UNIT_COL_NAME ] = self .snapshot_start .exposure .value_unit
10571085 return df
10581086
1059- def apply_measure (self , measure : Measure ) -> "CalcRiskMetricsPeriod" :
1060- """Creates a new `CalcRiskMetricsPeriod` object with a measure.
1061-
1062- The given measure is applied to both snapshot of the risk period.
1063-
1064- Parameters
1065- ----------
1066- measure : Measure
1067- The measure to apply.
10681087
1069- Returns
1070- -------
1071-
1072- CalcRiskPeriod
1073- The risk period with given measure applied.
1074-
1075- """
1076- snap0 = self .snapshot_start .apply_measure (measure )
1077- snap1 = self .snapshot_end .apply_measure (measure )
1078-
1079- risk_period = CalcRiskMetricsPeriod (
1080- snap0 ,
1081- snap1 ,
1082- self .time_resolution ,
1083- self .interpolation_strategy ,
1084- self .impact_computation_strategy ,
1085- )
1086-
1087- risk_period .measure = measure
1088- return risk_period
1088+ ####################################
1089+ ### Metrics from impact matrices ###
10891090
10901091
10911092def calc_per_date_eais (imp_mats : list [csr_matrix ], frequency : np .ndarray ) -> np .ndarray :
@@ -1106,10 +1107,9 @@ def calc_per_date_eais(imp_mats: list[csr_matrix], frequency: np.ndarray) -> np.
11061107 2D array of EAI (1D) for each dates.
11071108
11081109 """
1109- per_date_eai_exp = np .array (
1110+ return np .array (
11101111 [ImpactCalc .eai_exp_from_mat (imp_mat , frequency ) for imp_mat in imp_mats ]
11111112 )
1112- return per_date_eai_exp
11131113
11141114
11151115def calc_per_date_aais (per_date_eai_exp : np .ndarray ) -> np .ndarray :
@@ -1127,10 +1127,9 @@ def calc_per_date_aais(per_date_eai_exp: np.ndarray) -> np.ndarray:
11271127 np.ndarray
11281128 1D array of AAI (0D) for each dates.
11291129 """
1130- per_date_aai = np .array (
1130+ return np .array (
11311131 [ImpactCalc .aai_agg_from_eai_exp (eai_exp ) for eai_exp in per_date_eai_exp ]
11321132 )
1133- return per_date_aai
11341133
11351134
11361135def calc_per_date_rps (
@@ -1158,13 +1157,12 @@ def calc_per_date_rps(
11581157 2D array of impacts per return periods (1D) for each dates.
11591158
11601159 """
1161- rp = np .array (
1160+ return np .array (
11621161 [
11631162 calc_freq_curve (imp_mat , frequency , frequency_unit , return_periods ).impact
11641163 for imp_mat in imp_mats
11651164 ]
11661165 )
1167- return rp
11681166
11691167
11701168def calc_freq_curve (
0 commit comments