1717 StatisticalModel ,
1818 ecdf ,
1919 gen_PrecipitationGammaLeftCensoredModel ,
20+ iecdf ,
2021 threshold_cdf_vals ,
2122)
2223from ..variables import Variable , hurs , pr , psl , rlds , sfcwind , tas , tasmax , tasmin
@@ -156,6 +157,7 @@ class QuantileDeltaMapping(SeasonalAndFutureRunningWindowDebiaser):
156157 scipy .stats .rv_discrete ,
157158 scipy .stats .rv_histogram ,
158159 StatisticalModel ,
160+ None ,
159161 ] = attrs .field (
160162 validator = attrs .validators .instance_of (
161163 (
@@ -169,6 +171,10 @@ class QuantileDeltaMapping(SeasonalAndFutureRunningWindowDebiaser):
169171 trend_preservation : str = attrs .field (
170172 validator = attrs .validators .in_ (["absolute" , "relative" ])
171173 )
174+ mapping_type : str = attrs .field (
175+ default = "parametric" ,
176+ validator = attrs .validators .in_ (["parametric" , "nonparametric" ]),
177+ )
172178
173179 # Relevant for precipitation
174180 censor_values_to_zero : bool = attrs .field (
@@ -285,25 +291,28 @@ def apply_on_seasonal_and_future_window(
285291 Applies QuantileDeltaMapping at one location and returns the debiased timeseries.
286292 """
287293
288- fit_obs , fit_cm_hist = self ._get_obs_and_cm_hist_fits (obs , cm_hist )
289-
290- tau_t = threshold_cdf_vals (
294+ tau_m_p = threshold_cdf_vals (
291295 ecdf (cm_future , cm_future , method = self .ecdf_method ),
292296 cdf_threshold = self .cdf_threshold ,
293297 )
294298
295- if self .trend_preservation == "absolute" :
296- bias_corrected_vals = (
297- cm_future
298- + self .distribution .ppf (tau_t , * fit_obs )
299- - self .distribution .ppf (tau_t , * fit_cm_hist )
299+ if self .mapping_type == "nonparametric" :
300+ x_obs_to_cm_fut = iecdf (obs , tau_m_p )
301+ inv_F_cm_hist_tau = iecdf (cm_hist , tau_m_p )
302+ elif self .mapping_type == "parametric" :
303+ fit_obs , fit_cm_hist = self ._get_obs_and_cm_hist_fits (obs , cm_hist )
304+
305+ x_obs_to_cm_fut = self .distribution .ppf (tau_m_p , * fit_obs )
306+ inv_F_cm_hist_tau = self .distribution .ppf (tau_m_p , * fit_cm_hist )
307+ else :
308+ raise ValueError (
309+ 'self.mapping_type needs to be one of ["parametric", "nonparametric"]'
300310 )
311+
312+ if self .trend_preservation == "absolute" :
313+ bias_corrected_vals = x_obs_to_cm_fut + cm_future - inv_F_cm_hist_tau
301314 elif self .trend_preservation == "relative" :
302- bias_corrected_vals = (
303- cm_future
304- * self .distribution .ppf (tau_t , * fit_obs )
305- / self .distribution .ppf (tau_t , * fit_cm_hist )
306- )
315+ bias_corrected_vals = x_obs_to_cm_fut * cm_future / inv_F_cm_hist_tau
307316 else :
308317 raise ValueError (
309318 'self.trend_preservation needs to be one of ["absolute", "relative"]'
0 commit comments