Skip to content

Commit b3c1f13

Browse files
change error handling
1 parent 827ec99 commit b3c1f13

File tree

3 files changed

+49
-42
lines changed

3 files changed

+49
-42
lines changed

climada/engine/impact.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,17 @@ def local_exceedance_impact(
548548
column_label : function
549549
Column-label-generating function, for reporting and plotting
550550
551+
See Also
552+
--------
553+
util.interpolation.preprocess_and_interpolate_ev :
554+
inter- and extrapolation method
555+
551556
Notes
552557
-------
553558
Contrary to Impact.calc_freq_curve(), impacts are binned according to their n_sig_dig
554559
significant digits. This results in a coarser (and smoother) interpolation, and a
555-
more stable extrapolation. To not bin the values, please use, e.g., n_sig_dig=7. For more
556-
information about the binning, see docstring of
560+
more stable extrapolation. To not bin the values, please use a large value for n_sig_dig,
561+
e.g., n_sig_dig=7. For more information about the binning, see
557562
climada.util.interpolation.preprocess_and_interpolate_ev().
558563
"""
559564
LOGGER.info(
@@ -696,12 +701,17 @@ def local_return_period(
696701
column_label : function
697702
Column-label-generating function, for reporting and plotting
698703
704+
See Also
705+
--------
706+
util.interpolation.preprocess_and_interpolate_ev :
707+
inter- and extrapolation method
708+
699709
Notes
700710
-------
701711
Contrary to Impact.calc_freq_curve(), impacts are binned according to their n_sig_dig
702712
significant digits. This results in a coarser (and smoother) interpolation, and a
703-
more stable extrapolation. To not bin the values, please use, e.g., n_sig_dig=7. For more
704-
information about the binning, see docstring of
713+
more stable extrapolation. To not bin the values, please use a large value for n_sig_dig,
714+
e.g., n_sig_dig=7. For more information about the binning, see
705715
climada.util.interpolation.preprocess_and_interpolate_ev().
706716
"""
707717

climada/hazard/base.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -542,13 +542,19 @@ def local_exceedance_intensity(
542542
column_label : function
543543
Column-label-generating function, for reporting and plotting
544544
545+
See Also
546+
--------
547+
util.interpolation.preprocess_and_interpolate_ev :
548+
inter- and extrapolation method
549+
545550
Notes
546551
-------
547552
Contrary to Impact.calc_freq_curve(), intensities are binned according to their n_sig_dig
548553
significant digits. This results in a coarser (and smoother) interpolation, and a
549-
more stable extrapolation. To not bin the values, please use, e.g., n_sig_dig=7. For more
550-
information about the binning, see docstring of
551-
climada.util.interpolation.preprocess_and_interpolate_ev().
554+
more stable extrapolation. To not bin the values, please use a large value for n_sig_dig,
555+
e.g., n_sig_dig=7. For more information about the binning, see
556+
util.interpolation.preprocess_and_interpolate_ev().
557+
552558
"""
553559
if not min_intensity and min_intensity != 0:
554560
min_intensity = self.intensity_thres
@@ -688,12 +694,17 @@ def local_return_period(
688694
column_label : function
689695
Column-label-generating function, for reporting and plotting
690696
697+
See Also
698+
--------
699+
util.interpolation.preprocess_and_interpolate_ev :
700+
inter- and extrapolation method
701+
691702
Notes
692703
-------
693704
Contrary to Impact.calc_freq_curve(), intensities are binned according to their n_sig_dig
694705
significant digits. This results in a coarser (and smoother) interpolation, and a
695-
more stable extrapolation. To not bin the values, please use, e.g., n_sig_dig=7. For more
696-
information about the binning, see docstring of
706+
more stable extrapolation. To not bin the values, please use a large value for n_sig_dig,
707+
e.g., n_sig_dig=7. For more information about the binning, see
697708
climada.util.interpolation.preprocess_and_interpolate_ev().
698709
"""
699710
if not min_intensity and min_intensity != 0:

climada/util/interpolation.py

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,20 @@ def preprocess_and_interpolate_ev(
8989
If both test frequencies and test values are given or none of them.
9090
9191
Notes
92-
-------
92+
-----
9393
Before inter- and extrapolation, the values are binned according to their n_sig_dig
9494
significant digits, and their corresponding frequencies are summed. For instance, if
9595
n_sig_dig=3, the two values 12.01 and 11.97 with corresponding frequencies 0.1 and 0.2 are
96-
combined to a value 12.0 with frequency 0.3. This binning leads to a coarser (and smoother)
96+
combined to a value 12.0 with frequency 0.3. This binning leads to a smoother (and coarser)
9797
interpolation, and a more stable extrapolation. To not bin the values, you can use a large
9898
n_sig_dig, e.g., n_sig_dig=7.
9999
"""
100100

101101
# check that only test frequencies or only test values are given
102102
if test_frequency is not None and test_values is not None:
103103
raise ValueError(
104-
"Both test frequencies and test values are given. "
105-
"To use this method, please only use one of them."
104+
"Both test frequencies and test values are given. This method only handles one of "
105+
"the two. To use this method, please only use one of them."
106106
)
107107
elif test_frequency is None and test_values is None:
108108
raise ValueError("No test values or test frequencies are given.")
@@ -113,15 +113,15 @@ def preprocess_and_interpolate_ev(
113113
frequency = frequency[sorted_idxs]
114114

115115
# group similar values together
116-
frequency, values = group_frequency(frequency, values, n_sig_dig)
116+
frequency, values = _group_frequency(frequency, values, n_sig_dig)
117117

118118
# transform frequencies to cummulative frequencies
119119
frequency = np.cumsum(frequency[::-1])[::-1]
120120

121121
# if test frequencies are provided
122122
if test_frequency is not None:
123123
if method == "stepfunction":
124-
return stepfunction_ev(
124+
return _stepfunction_ev(
125125
test_frequency,
126126
frequency[::-1],
127127
values[::-1],
@@ -130,7 +130,7 @@ def preprocess_and_interpolate_ev(
130130
)
131131
else:
132132
extrapolation = None if method == "interpolate" else method
133-
return interpolate_ev(
133+
return _interpolate_ev(
134134
test_frequency,
135135
frequency[::-1],
136136
values[::-1],
@@ -144,7 +144,7 @@ def preprocess_and_interpolate_ev(
144144
# if test values are provided
145145
else:
146146
if method == "stepfunction":
147-
return stepfunction_ev(
147+
return _stepfunction_ev(
148148
test_values,
149149
values,
150150
frequency,
@@ -153,7 +153,7 @@ def preprocess_and_interpolate_ev(
153153
)
154154
else:
155155
extrapolation = None if method == "interpolate" else method
156-
return interpolate_ev(
156+
return _interpolate_ev(
157157
test_values,
158158
values,
159159
frequency,
@@ -164,7 +164,7 @@ def preprocess_and_interpolate_ev(
164164
)
165165

166166

167-
def interpolate_ev(
167+
def _interpolate_ev(
168168
x_test,
169169
x_train,
170170
y_train,
@@ -184,7 +184,7 @@ def interpolate_ev(
184184
x_test : array_like
185185
1-D array of x-values for which training data should be interpolated
186186
x_train : array_like
187-
1-D array of x-values of training data
187+
1-D array of x-values of training data sorted in ascending order
188188
y_train : array_like
189189
1-D array of y-values of training data
190190
logx : bool, optional
@@ -227,11 +227,6 @@ def interpolate_ev(
227227
if extrapolation == "extrapolate":
228228
fill_value = "extrapolate"
229229
elif extrapolation == "extrapolate_constant":
230-
if not all(sorted(x_train) == x_train):
231-
raise ValueError(
232-
"x_train array must be sorted in ascending order. This might be due to floating "
233-
"point errors in the rounding process of `group_frequency()`."
234-
)
235230
fill_value = (y_train[0], np.log10(y_asymptotic) if logy else y_asymptotic)
236231
else:
237232
fill_value = np.nan
@@ -247,7 +242,7 @@ def interpolate_ev(
247242
return y_test
248243

249244

250-
def stepfunction_ev(
245+
def _stepfunction_ev(
251246
x_test, x_train, y_train, x_threshold=None, y_threshold=None, y_asymptotic=np.nan
252247
):
253248
"""
@@ -259,7 +254,7 @@ def stepfunction_ev(
259254
x_test : array_like
260255
1-D array of x-values for which training data should be interpolated
261256
x_train : array_like
262-
1-D array of x-values of training data
257+
1-D array of x-values of training data sorted in ascending order
263258
y_train : array_like
264259
1-D array of y-values of training data
265260
x_threshold : float, optional
@@ -285,11 +280,6 @@ def stepfunction_ev(
285280
return _interpolate_small_input(x_test, x_train, y_train, None, y_asymptotic)
286281

287282
# find indices of x_test if sorted into x_train
288-
if not all(sorted(x_train) == x_train):
289-
raise ValueError(
290-
"Input array x_train must be sorted in ascending order. This might be due to "
291-
"floating point errors in the rounding process of `group_frequency()`."
292-
)
293283
indx = np.searchsorted(x_train, x_test)
294284
y_test = y_train[indx.clip(max=len(x_train) - 1)]
295285
y_test[indx == len(x_train)] = y_asymptotic
@@ -357,7 +347,7 @@ def _interpolate_small_input(x_test, x_train, y_train, logy, y_asymptotic):
357347
return y_test
358348

359349

360-
def group_frequency(frequency, value, n_sig_dig):
350+
def _group_frequency(frequency, value, n_sig_dig):
361351
"""
362352
Util function to aggregate (add) frequencies for equal values
363353
@@ -383,22 +373,18 @@ def group_frequency(frequency, value, n_sig_dig):
383373
# round values and group them
384374
value = round_to_sig_digits(value, n_sig_dig)
385375
value_unique, start_indices = np.unique(value, return_index=True)
386-
387376
if value_unique.size != frequency.size:
388377
if not all(sorted(start_indices) == start_indices):
389-
raise ValueError(
390-
"Value array must be sorted in ascending order. This might be due to floating "
391-
"point errors in the rounding process of `round_to_sig_digits()`."
378+
LOGGER.warning(
379+
"After grouping values to significant digits, the value array is not sorted."
380+
f"The values are not binned. Please choose a larger value of n_sig_dig={n_sig_dig}."
392381
)
382+
return frequency, value
383+
393384
# add frequency for equal value
394385
start_indices = np.insert(start_indices, value_unique.size, frequency.size)
395386
frequency = np.add.reduceat(frequency, start_indices[:-1])
396387
return frequency, value_unique
397-
elif not all(sorted(value) == value):
398-
raise ValueError(
399-
"Value array must be sorted in ascending order. This might be due to floating point "
400-
"errors in the rounding process of `round_to_sig_digits()`."
401-
)
402388

403389
return frequency, value
404390

0 commit comments

Comments
 (0)