Coverage for src/scores/probability/brier_impl.py: 100%

1"""

2 This module contains methods related to the Brier score

3"""

4

5 import xarray as xr

6

7 from scores.continuous import mse

8 from scores.processing import check_binary

9 from scores.typing import FlexibleArrayType, FlexibleDimensionTypes

10

11

12 def brier_score(

13 fcst: FlexibleArrayType,

14 obs: FlexibleArrayType,

15 reduce_dims: FlexibleDimensionTypes = None,

16 preserve_dims: FlexibleDimensionTypes = None,

17 weights: xr.DataArray = None,

18 check_args: bool = True,

19):

20 """

21 Calculates the Brier score for forecast and observed data. For an explanation of the

22 Brier score, see [Wikipedia](https://en.wikipedia.org/wiki/Brier_score).

23

24 If you want to speed up performance with Dask and are confident of your input data,

25 or if you want observations to take values between 0 and 1, set `check_inputs` to `False`.

26

27 Args:

28 fcst: Forecast or predicted variables in xarray.

29 obs: Observed variables in xarray.

30 reduce_dims: Optionally specify which dimensions to reduce when

31 calculating the Brier score. All other dimensions will be preserved.

32 preserve_dims: Optionally specify which dimensions to preserve when

33 calculating the Brier score. All other dimensions will be reduced. As a

34 special case, 'all' will allow all dimensions to be preserved. In

35 this case, the result will be in the same shape/dimensionality

36 as the forecast, and the errors will be the absolute error at each

37 point (i.e. single-value comparison against observed), and the

38 forecast and observed dimensions must match precisely.

39 weights: Optionally provide an array for weighted averaging (e.g. by area, by latitude,

40 by population, custom)

41 Raises:

42 ValueError: if `fcst` contains non-nan values outside of the range [0, 1]

43 ValueError: if `obs` contains non-nan values not in the set {0, 1}

44 """

45 if check_args:

46 error_msg = ValueError("`fcst` contains values outside of the range [0, 1]")

47 if isinstance(fcst, xr.Dataset):

48 # The .values is required as item() is not yet a valid method on Dask

49 if fcst.to_array().max().values.item() > 1 or fcst.to_array().min().values.item() < 0:

50 raise error_msg

51 else:

52 if fcst.max().values.item() > 1 or fcst.min().values.item() < 0:

53 raise error_msg

54 check_binary(obs, "obs")

55

56 return mse(fcst, obs, reduce_dims, preserve_dims, weights)