diff --git a/docs/api.md b/docs/api.md index 605427e4..f9bb8c79 100644 --- a/docs/api.md +++ b/docs/api.md @@ -40,8 +40,8 @@ .. autofunction:: scores.probability.crps_step_threshold_weight .. autofunction:: scores.probability.crps_cdf_brier_decomposition .. autofunction:: scores.probability.crps_for_ensemble -.. autofunction:: scores.probability.twcrps_for_ensemble -.. autofunction:: scores.probability.tail_twcrps_for_ensemble +.. autofunction:: scores.probability.tw_crps_for_ensemble +.. autofunction:: scores.probability.tail_tw_crps_for_ensemble .. autofunction:: scores.probability.murphy_score .. autofunction:: scores.probability.murphy_thetas .. autofunction:: scores.probability.roc_curve_data diff --git a/docs/included.md b/docs/included.md index fa4c9fd1..a875b721 100644 --- a/docs/included.md +++ b/docs/included.md @@ -221,11 +221,11 @@ - — - — * - Tail Threshold Weighted Continuous Ranked Probability Score (twCRPS) for Ensembles - - [API](api.md#scores.probability.tail_twcrps_for_ensemble) + - [API](api.md#scores.probability.tail_tw_crps_for_ensemble) - — - [Allen et al. (2023)](https://doi.org/10.1137/22M1532184) * - Threshold Weighted Continuous Ranked Probability Score (twCRPS) for Ensembles - - [API](api.md#scores.probability.twcrps_for_ensemble) + - [API](api.md#scores.probability.tw_crps_for_ensemble) - — - [Allen et al. (2023)](https://doi.org/10.1137/22M1532184) ``` diff --git a/src/scores/probability/__init__.py b/src/scores/probability/__init__.py index 44e57c6a..e794c740 100644 --- a/src/scores/probability/__init__.py +++ b/src/scores/probability/__init__.py @@ -10,8 +10,8 @@ crps_cdf_brier_decomposition, crps_for_ensemble, crps_step_threshold_weight, - tail_twcrps_for_ensemble, - twcrps_for_ensemble, + tail_tw_crps_for_ensemble, + tw_crps_for_ensemble, ) from scores.probability.roc_impl import roc_curve_data from scores.processing.isoreg_impl import isotonic_fit @@ -27,6 +27,6 @@ "roc_curve_data", "isotonic_fit", "crps_step_threshold_weight", - "twcrps_for_ensemble", - "tail_twcrps_for_ensemble", + "tw_crps_for_ensemble", + "tail_tw_crps_for_ensemble", ] diff --git a/src/scores/probability/crps_impl.py b/src/scores/probability/crps_impl.py index da557cf7..c85d98d0 100644 --- a/src/scores/probability/crps_impl.py +++ b/src/scores/probability/crps_impl.py @@ -826,8 +826,8 @@ def crps_for_ensemble( See also: :py:func:`scores.probability.crps_cdf` - :py:func:`scores.probability.twcrps_for_ensemble` - :py:func:`scores.probability.tail_twcrps_for_ensemble` + :py:func:`scores.probability.tw_crps_for_ensemble` + :py:func:`scores.probability.tail_tw_crps_for_ensemble` References: - C. Ferro (2014), "Fair scores for ensemble forecasts", Quarterly Journal of the \ @@ -876,7 +876,7 @@ def crps_for_ensemble( return result # type: ignore -def twcrps_for_ensemble( +def tw_crps_for_ensemble( fcst: XarrayLike, obs: XarrayLike, ensemble_member_dim: str, @@ -964,7 +964,7 @@ def twcrps_for_ensemble( See also:ß :py:func:`scores.probability.crps_for_ensemble` - :py:func:`scores.probability.tail_twcrps_for_ensemble` + :py:func:`scores.probability.tail_tw_crps_for_ensemble` :py:func:`scores.probability.crps_cdf` @@ -975,10 +975,10 @@ def twcrps_for_ensemble( >>> import numpy as np >>> import xarray as xr - >>> from scores.probability import twcrps_for_ensemble + >>> from scores.probability import tw_crps_for_ensemble >>> fcst = xr.DataArray(np.random.rand(10, 10), dims=['time', 'ensemble']) >>> obs = xr.DataArray(np.random.rand(10), dims=['time']) - >>> twcrps_for_ensemble(fcst, obs, 'ensemble', lambda x: np.maximum(x, 0.5)) + >>> tw_crps_for_ensemble(fcst, obs, 'ensemble', lambda x: np.maximum(x, 0.5)) """ @@ -996,7 +996,7 @@ def twcrps_for_ensemble( return result -def tail_twcrps_for_ensemble( +def tail_tw_crps_for_ensemble( fcst: XarrayLike, obs: XarrayLike, ensemble_member_dim: str, @@ -1018,7 +1018,7 @@ def tail_twcrps_for_ensemble( For example, if we only care about values above 40 degrees C, we can set ``threshold=40`` and ``tail="upper"``. For more flexible weighting options and the relevant equations, see the - :py:func:`scores.probability.twcrps_for_ensemble` function. + :py:func:`scores.probability.tw_crps_for_ensemble` function. Args: fcst: Forecast data. Must have a dimension `ensemble_member_dim`. @@ -1049,7 +1049,7 @@ def tail_twcrps_for_ensemble( Quantification, 11(3), 906-940. https://doi.org/10.1137/22M1532184 See also: - :py:func:`scores.probability.twcrps_for_ensemble` + :py:func:`scores.probability.tw_crps_for_ensemble` :py:func:`scores.probability.crps_for_ensemble` :py:func:`scores.probability.crps_cdf` @@ -1059,10 +1059,10 @@ def tail_twcrps_for_ensemble( >>> import numpy as np >>> import xarray as xr - >>> from scores.probability import tail_twcrps_for_ensemble + >>> from scores.probability import tail_tw_crps_for_ensemble >>> fcst = xr.DataArray(np.random.rand(10, 10), dims=['time', 'ensemble']) >>> obs = xr.DataArray(np.random.rand(10), dims=['time']) - >>> tail_twcrps_for_ensemble(fcst, obs, 'ensemble', 0.5, tail='upper') + >>> tail_tw_crps_for_ensemble(fcst, obs, 'ensemble', 0.5, tail='upper') """ if tail not in ["upper", "lower"]: @@ -1077,7 +1077,7 @@ def _vfunc(x): def _vfunc(x): return np.minimum(x, threshold) - result = twcrps_for_ensemble( + result = tw_crps_for_ensemble( fcst, obs, ensemble_member_dim, diff --git a/tests/probabilty/test_crps.py b/tests/probabilty/test_crps.py index f6ca5c05..7fe50905 100644 --- a/tests/probabilty/test_crps.py +++ b/tests/probabilty/test_crps.py @@ -18,8 +18,8 @@ crps_cdf, crps_cdf_brier_decomposition, crps_for_ensemble, - tail_twcrps_for_ensemble, - twcrps_for_ensemble, + tail_tw_crps_for_ensemble, + tw_crps_for_ensemble, ) from scores.probability.crps_impl import ( crps_cdf_exact, @@ -802,9 +802,9 @@ def test_crps_for_ensemble_dask(): ), ], ) -def test_tail_twcrps_for_ensemble(fcst, obs, method, tail, threshold, preserve_dims, reduce_dims, weights, expected): - """Tests tail_twcrps_for_ensembles""" - result = tail_twcrps_for_ensemble( +def test_tail_tw_crps_for_ensemble(fcst, obs, method, tail, threshold, preserve_dims, reduce_dims, weights, expected): + """Tests tail_tw_crps_for_ensembles""" + result = tail_tw_crps_for_ensemble( fcst, obs, ensemble_member_dim="ens_member", @@ -818,14 +818,14 @@ def test_tail_twcrps_for_ensemble(fcst, obs, method, tail, threshold, preserve_d xr.testing.assert_allclose(result, expected) -def test_tail_twcrps_for_ensemble_dask(): - """Tests `tail_twcrps_for_ensemble` works with dask.""" +def test_tail_tw_crps_for_ensemble_dask(): + """Tests `tail_tw_crps_for_ensemble` works with dask.""" if dask == "Unavailable": # pragma: no cover pytest.skip("Dask unavailable, could not run test") # pragma: no cover # Check that it works with xr.Datarrays - result = tail_twcrps_for_ensemble( + result = tail_tw_crps_for_ensemble( fcst=crps_test_data.DA_FCST_CRPSENS.chunk(), obs=crps_test_data.DA_OBS_CRPSENS.chunk(), ensemble_member_dim="ens_member", @@ -842,7 +842,7 @@ def test_tail_twcrps_for_ensemble_dask(): xr.testing.assert_allclose(result, crps_test_data.EXP_UPPER_TAIL_CRPSENS_ECDF_DA) # Check that it works with xr.Datasets - result_ds = tail_twcrps_for_ensemble( + result_ds = tail_tw_crps_for_ensemble( fcst=crps_test_data.DS_FCST_CRPSENS.chunk(), obs=crps_test_data.DS_OBS_CRPSENS.chunk(), ensemble_member_dim="ens_member", @@ -859,9 +859,9 @@ def test_tail_twcrps_for_ensemble_dask(): xr.testing.assert_allclose(result_ds, crps_test_data.EXP_UPPER_TAIL_CRPSENS_ECDF_DS) -def test_tail_twcrps_for_ensemble_raises(): +def test_tail_tw_crps_for_ensemble_raises(): with pytest.raises(ValueError, match="'middle' is not one of 'upper' or 'lower'"): - result = tail_twcrps_for_ensemble( + result = tail_tw_crps_for_ensemble( fcst=crps_test_data.DA_FCST_CRPSENS, obs=crps_test_data.DA_OBS_CRPSENS, ensemble_member_dim="ens_member", @@ -872,22 +872,22 @@ def test_tail_twcrps_for_ensemble_raises(): def v_func1(x): - """For testing twcrps_for_ensembles. The equivalent of a tail weight for thresholds 1 and higher""" + """For testing tw_crps_for_ensembles. The equivalent of a tail weight for thresholds 1 and higher""" return np.maximum(x, 1) def v_func2(x): - """For testing twcrps_for_ensembles. The equivalent of the unweighted CRPS""" + """For testing tw_crps_for_ensembles. The equivalent of the unweighted CRPS""" return x def v_func3(x): - """For testing twcrps_for_ensembles. The equivalent of a tail weight for thresholds that vary across a dimension""" + """For testing tw_crps_for_ensembles. The equivalent of a tail weight for thresholds that vary across a dimension""" return np.maximum(x, crps_test_data.DA_T_TWCRPSENS) def v_func4(x): - """For testing twcrps_for_ensembles. The equivalent of a tail weight for thresholds that vary across a dimension with a xr.dataset""" + """For testing tw_crps_for_ensembles. The equivalent of a tail weight for thresholds that vary across a dimension with a xr.dataset""" return np.maximum(x, crps_test_data.DS_T_TWCRPSENS) @@ -985,10 +985,10 @@ def v_func4(x): ), ], ) -def test_twcrps_for_ensemble(fcst, obs, method, v_func, preserve_dims, reduce_dims, weights, expected): - """Tests twcrps_for_ensembles""" +def test_tw_crps_for_ensemble(fcst, obs, method, v_func, preserve_dims, reduce_dims, weights, expected): + """Tests tw_crps_for_ensembles""" - result = twcrps_for_ensemble( + result = tw_crps_for_ensemble( fcst, obs, ensemble_member_dim="ens_member", @@ -1001,9 +1001,9 @@ def test_twcrps_for_ensemble(fcst, obs, method, v_func, preserve_dims, reduce_di xr.testing.assert_allclose(result, expected) -def test_twcrps_for_ensemble_dask(): - """Tests `twcrps_for_ensemble` works with dask.""" - result = twcrps_for_ensemble( +def test_tw_crps_for_ensemble_dask(): + """Tests `tw_crps_for_ensemble` works with dask.""" + result = tw_crps_for_ensemble( fcst=crps_test_data.DA_FCST_CRPSENS.chunk(), obs=crps_test_data.DA_OBS_CRPSENS.chunk(), ensemble_member_dim="ens_member", @@ -1019,7 +1019,7 @@ def test_twcrps_for_ensemble_dask(): xr.testing.assert_allclose(result, crps_test_data.EXP_UPPER_TAIL_CRPSENS_ECDF_DA) # Check that it works with xr.Datasets - result_ds = twcrps_for_ensemble( + result_ds = tw_crps_for_ensemble( fcst=crps_test_data.DS_FCST_CRPSENS.chunk(), obs=crps_test_data.DS_OBS_CRPSENS.chunk(), ensemble_member_dim="ens_member",