Coverage for src/scores/functions.py: 100%
16 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
1from typing import overload
3import numpy as np
4import xarray as xr
6from scores.typing import XarrayLike
9def apply_weights(values, weights=None):
10 """
11 Returns:
12 A new array with the elements of values multiplied by the specified weights.
14 Args:
15 - weights: The weightings to be used at every location in the values array. If weights contains additional
16 dimensions, these will be taken to mean that multiple weightings are wanted simultaneoulsy, and these
17 dimensions will be added to the new array.
18 - values: The unweighted values to be used as the basis for weighting calculation
21 Note - this weighting function is different to the .weighted method contained in xarray in that xarray's
22 method does not allow NaNs to be present in the weights or data.
23 """
25 if weights is not None:
26 result = values * weights
27 return result
29 return values
32def create_latitude_weights(latitudes):
33 """
34 A common way of weighting errors is to make them proportional to the amount of area
35 which is contained in a particular region. This is approximated by the cosine
36 of the latitude on an LLXY grid. Nuances not accounted for include the variation in
37 latitude across the region, or the irregularity of the surface of the earth.
39 Returns:
40 An xarray containing the weight values to be used for area approximation
42 Args:
43 An xarray (or castable type) containing latitudes between +90 and -90 degrees
45 Note - floating point behaviour can vary between systems, precisions and other factors
46 """
47 weights = np.cos(np.deg2rad(latitudes))
48 return weights
51# Dataset input types lead to a Dataset return type
52@overload
53def angular_difference(source_a: xr.Dataset, source_b: xr.Dataset) -> xr.Dataset:
54 ...
57# DataArray input types lead to a DataArray return type
58@overload
59def angular_difference(source_a: xr.DataArray, source_b: xr.DataArray) -> xr.DataArray:
60 ...
63def angular_difference(source_a: XarrayLike, source_b: XarrayLike) -> XarrayLike:
64 """
65 Determines, in degrees, the smaller of the two explementary angles between
66 two sources of directional data (e.g. wind direction).
68 Args:
69 source_a: direction data in degrees, first source
70 source_b: direction data in degrees, second source
72 Returns:
73 An array containing angles within the range [0, 180].
74 """
75 difference = np.abs(source_a - source_b) % 360
76 difference = difference.where(difference <= 180, 360 - difference)
77 return difference