Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve SPI performance #1311

Merged
merged 89 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
be3b9c6
pr_cal now created within SPI + refactoring
coxipi Feb 28, 2023
2d5b942
Better variable name
coxipi Feb 28, 2023
a939edb
params can be used as input, and computed beforehand (`get_params`)
coxipi Mar 1, 2023
aeb8038
Clearer var names and better doc
coxipi Mar 1, 2023
3c5ac71
Remove uses_range
coxipi Mar 1, 2023
ed4164d
cal_range type changed, new warnings
coxipi Mar 1, 2023
8f22ff1
cal_range type change 2/2
coxipi Mar 1, 2023
cbca142
fitting/rolling/resampling defined in a separate function
coxipi Mar 1, 2023
16f4b6b
resampling/rolling/fitting out of SPI
coxipi Mar 2, 2023
e990406
Update doc and formatting
coxipi Mar 2, 2023
ca577c2
indexer support
coxipi Mar 2, 2023
fde2441
update doc
coxipi Mar 2, 2023
f9c28c6
Merge branch 'master' into fix_spi_performance
Zeitsperre Mar 8, 2023
f9c73f4
Merge branch 'master' into fix_spi_performance
Zeitsperre Mar 10, 2023
0fa83f4
typo function isnull
coxipi Mar 15, 2023
5b3bbe6
Merge branch 'fix_spi_performance' of https://github.com/Ouranosinc/x…
coxipi Mar 15, 2023
f747dea
More documentation, remove useless step
coxipi Jun 19, 2023
2b6dfe9
Refactoring, simplifications, shorter msgs
coxipi Jun 22, 2023
09d72b3
More documentation, some cleaning
coxipi Jun 22, 2023
17c1463
SPI accepts da & params as sufficient arguments
coxipi Jun 28, 2023
d6d11d8
Merge branch 'master' into fix_spi_performance
Zeitsperre Jun 28, 2023
d2dd196
Remove problem in declare_units and move functions
coxipi Jun 30, 2023
50b7f71
remvoe pr_cal from declare_units
coxipi Jun 30, 2023
fdef084
Refactor functions names, no more "spx"
coxipi Jul 1, 2023
3f90a30
faster _get_standardized_index & refactoring
coxipi Jul 11, 2023
b02750b
fix variable names
coxipi Jul 11, 2023
e81ad73
Fixing SPEI units
coxipi Jul 11, 2023
5b7d483
add issue number
coxipi Jul 11, 2023
f8bae10
cal_range -> cal_{start|end} && offset in SPEI public
coxipi Jul 14, 2023
900225e
remove DATE_TUPLE type, etc
coxipi Jul 14, 2023
b60cd2d
Add offset as possible input in standardized_fit_params
coxipi Jul 20, 2023
4a293a3
new test on modularity and fix API error in SPI
coxipi Jul 20, 2023
fec71df
update CHANGES
coxipi Jul 21, 2023
993b639
remove comments
coxipi Jul 21, 2023
10fc30b
Merge branch 'master' into fix_spi_performance
Zeitsperre Jul 24, 2023
f3c0b0f
Merge branch 'master' into fix_spi_performance
Zeitsperre Jul 25, 2023
c8891c9
clipped std_index values
coxipi Jul 27, 2023
410c86d
Merge branch 'fix_spi_performance' of https://github.com/Ouranosinc/x…
coxipi Jul 27, 2023
486d5fe
format docstring
coxipi Jul 27, 2023
852bb07
Better description CHANGES.rst
coxipi Jul 27, 2023
fcbca5e
Merge branch 'master' into fix_spi_performance
Zeitsperre Jul 31, 2023
f62cf04
remove unrelated comments
coxipi Aug 1, 2023
85b815f
Merge branch 'fix_spi_performance' of https://github.com/Ouranosinc/x…
coxipi Aug 1, 2023
64052a5
more docuemntation on std_index bounds
coxipi Aug 1, 2023
c69c9cf
Merge branch 'master' of https://github.com/Ouranosinc/xclim into fix…
coxipi Aug 2, 2023
9b5b3b3
Merge branch 'master' into fix_spi_performance
coxipi Aug 14, 2023
abdc00b
Broadcast params if needed
coxipi Aug 16, 2023
7782481
Merge branch 'fix_spi_performance' of https://github.com/Ouranosinc/x…
coxipi Aug 16, 2023
2b26e88
Use template to broadcast
coxipi Aug 16, 2023
6bba201
better notation
coxipi Aug 16, 2023
ea1d3ea
correct function name in docstring test
coxipi Aug 16, 2023
35f3897
Merge branch 'master' into fix_spi_performance
Zeitsperre Aug 25, 2023
485e718
Improve description of SPEI offset
coxipi Sep 11, 2023
8f1868e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 11, 2023
06271eb
add notes about NaNs probable origin in SPEI
coxipi Sep 11, 2023
bd1d122
Merge branch 'master' of https://github.com/Ouranosinc/xclim into fix…
coxipi Sep 12, 2023
18f346d
Update CHANGES
coxipi Sep 12, 2023
b15e566
Improve documentation (review)
coxipi Sep 12, 2023
25c1d01
Improve documentation (review) 2/2
coxipi Sep 12, 2023
a2283bf
add docstring for _get_standardized_index
coxipi Sep 12, 2023
02f3821
Merge branch 'fix_spi_performance' of https://github.com/Ouranosinc/x…
coxipi Sep 12, 2023
693f588
typo in docsring
coxipi Sep 12, 2023
272d479
Merge branch 'master' into fix_spi_performance
Zeitsperre Oct 10, 2023
211c955
simpler loop over group_idx
coxipi Oct 18, 2023
a71963f
Merge branch 'fix_spi_performance' of https://github.com/Ouranosinc/x…
coxipi Oct 18, 2023
e0f008e
Merge branch 'master' of https://github.com/Ouranosinc/xclim into fix…
coxipi Oct 18, 2023
b3d3713
more comments, update docstrings
coxipi Oct 18, 2023
f6acc45
more simple management of the SPEI offset
coxipi Oct 18, 2023
1553208
Merge branch 'master' into fix_spi_performance
Zeitsperre Oct 18, 2023
2ca3f1c
Merge branch 'master' into fix_spi_performance
Zeitsperre Oct 18, 2023
c717169
Better doc & simplifications (review)
coxipi Oct 18, 2023
19deb92
only accept "D" & "MS" freqs
coxipi Oct 19, 2023
2aefe81
put std_index functions in stats.py, get rid of group_idx loop
coxipi Oct 19, 2023
96e320a
non-hardcoded definition of group indices
coxipi Oct 19, 2023
ffa1e10
correct infer_freq usage
coxipi Oct 20, 2023
3e28bbb
optimized dist_method to simplify std_index functions
coxipi Oct 21, 2023
b809ab6
remove uneeded function name in header
coxipi Oct 21, 2023
cc8b3e6
fix xci -> xci.stat where appropriate
coxipi Oct 23, 2023
3b4b8f2
typo
coxipi Oct 23, 2023
9ec645a
remove useless input/output core_dims from xr.apply_ufunc
coxipi Oct 23, 2023
3279515
Merge branch 'master' of https://github.com/Ouranosinc/xclim into fix…
coxipi Oct 23, 2023
845cac4
no need to broadcast `params_norm`
coxipi Oct 23, 2023
e461450
Merge branch 'master' into fix_spi_performance
Zeitsperre Oct 23, 2023
c702e48
fix merge of CHANGES.rst
Zeitsperre Oct 23, 2023
b3b9d7c
docstring and typing adjustments
Zeitsperre Oct 23, 2023
6929929
Merge remote-tracking branch 'origin/fix_spi_performance' into fix_sp…
Zeitsperre Oct 23, 2023
69ab14a
whitespace
Zeitsperre Oct 23, 2023
7f46856
Update CHANGES.rst (review)
coxipi Oct 23, 2023
59e7df6
only chunk if necessary, check if dask used (review)
coxipi Oct 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ New features and enhancements
* Indicator ``generic.stats`` now accepts any frequency (previously only daily). (:pull:`1498`).
* Added argument ``out_units`` to ``select_resample_op`` to bypass limitations of ``to_agg_units`` in custom indicators. Add "var" to supported operations in ``to_agg_units``. (:pull:`1498`).
* `adapt_freq_thresh` argument added `sdba` training functions, allowing to perform frequency adaptation appropriately in each map block. (:pull:`1407`).
* Standardized indices (``xclim.indices.standardized_precipitation_index`` and ``xclim.indices.standardized_precipitation_evapotranspiration_index``) (:issue:`1270`, :issue:`1416`, :issue:`1474`, :pull:`1311`) were changed:
* Optimized and noticeably faster calculation.
* Can be computed in two steps: First compute fit parameters with ``xclim.indices.stats.standardized_index_fit_params``, then use the output in the standardized indices functions.
* The standardized index values are now clipped to ±8.21. This reflects the ``float64`` precision of the computation when cumulative distributed function values are inverted to a normal distribution and avoids returning infinite values.
* An offset parameter is now available to account for negative water balance values``xclim.indices.standardized_precipitation_evapotranspiration_index``.

Bug fixes
^^^^^^^^^
Expand All @@ -41,6 +46,7 @@ Breaking changes
* Default threshold in ``xclim.indices.snw_season_{start|length|end}`` changed form `20 kg m-2` to `4 kg m-2`. (:pull:`1505`).
* `xclim` development dependencies now include `ruff`. `pycodestyle` and `pydocstyle` have been replaced by `ruff` and removed from the `dev` installation recipe. (:pull:`1504`).
* The `mf_file` call signature found in ``xclim.ensembles.create_ensemble`` (and ``xclim.ensembles._ens_align_dataset``) has been removed (deprecated since `xclim` v0.43.0). (:pull:`1506`).
* ``xclim.indices.standardized_precipitation_index`` and ``xclim.indices.standardized_precipitation_evapotranspiration_index`` will no longer accept two datasets (data and calibration data). Instead, a single dataset covering both the calibration and evaluation periods is expected. (:issue:`1270`, :pull:`1311`).

Internal changes
^^^^^^^^^^^^^^^^
Expand Down
63 changes: 57 additions & 6 deletions tests/test_indices.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,10 +526,10 @@ def test_standardized_precipitation_index(
ds = open_dataset("sdba/CanESM2_1950-2100.nc").isel(location=1)
pr = ds.pr.sel(time=slice("1998", "2000"))
pr_cal = ds.pr.sel(time=slice("1950", "1980"))
spi = xci.standardized_precipitation_index(
pr, pr_cal, freq, window, dist, method
params = xci.stats.standardized_index_fit_params(
pr_cal, freq=freq, window=window, dist=dist, method=method
)

spi = xci.standardized_precipitation_index(pr, params=params)
# Only a few moments before year 2000 are tested
spi = spi.isel(time=slice(-11, -1, 2))

Expand Down Expand Up @@ -610,11 +610,17 @@ def test_standardized_precipitation_evapotranspiration_index(
tas = tasmax - 2.5
tasmin = tasmax - 5
wb = xci.water_budget(pr, None, tasmin, tasmax, tas)
wb_cal = wb.sel(time=slice("1950", "1980"))
wb = wb.sel(time=slice("1998", "2000"))

params = xci.stats.standardized_index_fit_params(
wb.sel(time=slice("1950", "1980")),
freq=freq,
window=window,
dist=dist,
method=method,
offset="1 mm/d",
)
spei = xci.standardized_precipitation_evapotranspiration_index(
wb, wb_cal, freq, window, dist, method
wb.sel(time=slice("1998", "2000")), params=params
)

# Only a few moments before year 2000 are tested
Expand All @@ -625,6 +631,51 @@ def test_standardized_precipitation_evapotranspiration_index(

np.testing.assert_allclose(spei.values, values, rtol=0, atol=diff_tol)

def test_standardized_index_modularity(self, open_dataset):
freq, window, dist, method = "MS", 6, "gamma", "APP"
ds = (
open_dataset("sdba/CanESM2_1950-2100.nc")
.isel(location=1)
.sel(time=slice("1950", "2000"))
)
pr = ds.pr
# generate water budget
with xr.set_options(keep_attrs=True):
tasmax = ds.tasmax
tas = tasmax - 2.5
tasmin = tasmax - 5
wb = xci.water_budget(pr, None, tasmin, tasmax, tas)

params = xci.stats.standardized_index_fit_params(
wb.sel(time=slice("1950", "1980")),
freq=freq,
window=window,
dist=dist,
method=method,
offset="1 mm/d",
)
spei1 = xci.standardized_precipitation_evapotranspiration_index(
wb.sel(time=slice("1998", "2000")), params=params
)

spei2 = xci.standardized_precipitation_evapotranspiration_index(
wb,
freq=freq,
window=window,
dist=dist,
method=method,
offset="1 mm/d",
cal_start="1950",
cal_end="1980",
).sel(time=slice("1998", "2000"))

# In the previous computation, the first {window-1} values are NaN because the rolling is performed on the period [1998,2000].
# Here, the computation is performed on the period [1950,2000], *then* subsetted to [1998,2000], so it doesn't have NaNs
# for the first values
spei2[{"time": slice(0, window - 1)}] = np.nan

np.testing.assert_allclose(spei1.values, spei2.values, rtol=0, atol=1e-4)


class TestDailyFreezeThawCycles:
@pytest.mark.parametrize(
Expand Down
Loading