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

Fitted paramers reloaded from NC lead to errors in standardized index, and setting multiple indexers leads to inconsistent behaviour #1842

Closed
2 tasks done
Hem-W opened this issue Jul 18, 2024 · 1 comment · Fixed by #1843
Labels
bug Something isn't working

Comments

@Hem-W
Copy link
Contributor

Hem-W commented Jul 18, 2024

Setup Information

  • Xclim version: 0.51.0
  • Python version: 3.11.8
  • Operating System: Ubuntu 20.04

Description

The time indexer in the xc.indices.stats.standardized_index_fit_params was not correctly stored in the attributes, leading to errors in different cases:

  1. When there is no indexer, the indexer in the xc.indices.stats.standardized_index_fit_params was changed after to_netcdf and reloaded from xr.open_dataset(), leading to an error when running standardized_precipitation_index(pr, params=params);
  2. When the value of indexer is a non-array single value, there will be an error when encoding the attribute params.attrs["time_indexer"] in stats.standardized_index_fit_params;
  3. When there are multiple indexers, only one indexer is saved, leading to inconsistent behaviour when running standardized_precipitation_index(pr, params=params).

Steps To Reproduce

Load dataset:

import xarray as xr
import xclim.indices as xci
from xclim.testing import open_dataset

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"))
params = xci.stats.standardized_index_fit_params(
    pr_cal, freq="MS", window=1, dist="gamma", method="APP", fitkwargs={"floc": 0}, zero_inflated=True)

For the first issue,

params.to_dataset(name="params").to_netcdf("params.nc")
params = xr.open_dataset("params.nc").params

spi = xci.standardized_precipitation_index(pr, params=params)  # this line leads to the error

For the second issue,

params = xci.stats.standardized_index_fit_params(
    pr_cal, freq="MS", window=1, dist="gamma", method="APP", fitkwargs={"floc": 0}, zero_inflated=True, month=2)
# executable only when an array is assigned to `month`

For the third issue,

params = xci.stats.standardized_index_fit_params(
    pr_cal, freq="MS", window=1, dist="gamma", method="APP", fitkwargs={"floc": 0}, zero_inflated=True, drop=True, month=[2, 3])  # `drop=True` is not saved in params.attrs["time_indexer"]`
xci.standardized_precipitation_index(pr, params=params)  # the months other than 2 & 3 were not dropped

Additional context

The error logs are attached here.
For the first issue,

File ~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:882, in standardized_index(da, freq, window, dist, method, zero_inflated, fitkwargs, cal_start, cal_end, params, **indexer)
    [880](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:880) # Unpack attrs to None and {} if needed
    [881](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:881) freq = None if freq == "" else freq
--> [882](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:882) indexer = {} if indexer[0] == "" else {indexer[0]: indexer[1:]}
    [883](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:883) if cal_start or cal_end:
    [884](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:884)     warnings.warn(
    [885](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:885)         "Expected either `cal_{start|end}` or `params`, got both. The `params` input overrides other inputs."
    [886](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:886)         "If `cal_start`, `cal_end`, `freq`, `window`, and/or `dist` were given as input, they will be ignored."
    [887](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:887)     )

IndexError: string index out of range

For the second issue,

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[3], [line 1](vscode-notebook-cell:?execution_count=3&line=1)
----> [1](vscode-notebook-cell:?execution_count=3&line=1) params = xci.stats.standardized_index_fit_params(
      [2](vscode-notebook-cell:?execution_count=3&line=2)     pr_cal, freq="MS", window=1, dist="gamma", method="APP", fitkwargs={"floc": 0}, zero_inflated=True, month=2)

File ~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:801, in standardized_index_fit_params(da, freq, window, dist, method, zero_inflated, fitkwargs, offset, **indexer)
    [791](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:791) params.attrs = {
    [792](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:792)     "calibration_period": cal_range,
    [793](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:793)     "freq": freq or "",
   (...)
    [798](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:798)     "units": "",
    [799](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:799) }
    [800](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:800) method, args = ("", []) if indexer == {} else indexer.popitem()
--> [801](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:801) params.attrs["time_indexer"] = (method, *args)
    [802](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:802) if offset:
    [803](~/.conda/envs/syncfuture/lib/python3.11/site-packages/xclim/indices/stats.py:803)     params.attrs["offset"] = offset

For the third issue, the attributes in the params are like

and the obtained SPI would be like
WX20240718-125333@2x.

Contribution

  • I would be willing/able to open a Pull Request to address this bug.

Code of Conduct

  • I agree to follow this project's Code of Conduct
@Hem-W Hem-W added the bug Something isn't working label Jul 18, 2024
@Hem-W Hem-W changed the title Reloading fitted paramers (standardized_index_fit_params) from netCDF lead to errors, and setting multiple indexer would lead to inconsistent behaviour Reloading fitted paramers from NC leads to errors, and setting multiple indexer leads to inconsistent behaviour Jul 18, 2024
@Hem-W Hem-W changed the title Reloading fitted paramers from NC leads to errors, and setting multiple indexer leads to inconsistent behaviour Fitted paramers reloaded from NC lead to errors in standardized index, and setting multiple indexers leads to inconsistent behaviour Jul 18, 2024
@aulemahal
Copy link
Collaborator

Thanks for the issue @Hem-W ! Indeed, we only tested this mechanic by loading the params in-memory, and forgot about all these issues when going through netCDF!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants