improver.wind_calculations.wind_direction module

Module containing wind direction averaging plugins.

class WindDirection(backup_method='neighbourhood')[source]

Bases: PostProcessingPlugin

Plugin to calculate average wind direction from ensemble realizations.

Science background: Taking an average wind direction is tricky since an average of two wind directions at 10 and 350 degrees is 180 when it should be 0 degrees. Converting the wind direction angles to complex numbers allows us to find a useful numerical average.

z = a + bi
a = r*Cos(theta)
b = r*Sin(theta)
r = radius

The average of two complex numbers is NOT the ANGLE between two points it is the MIDPOINT in cartesian space. Therefore if there are two data points with radius=1 at 90 and 270 degrees then the midpoint is at (0,0) with radius=0 and therefore its average angle is meaningless.

           N
           |
W---x------o------x---E
           |
           S

In the rare case that a meaningless complex average is calculated, the code rejects the calculated complex average and simply uses the wind direction taken from the first ensemble realization.

The steps are:

  1. Take data from all ensemble realizations.

  2. Convert the wind direction angles to complex numbers.

  3. Find complex average and their radius values.

  4. Convert the complex average back into degrees.

  5. If any point has an radius of nearly zero - replace the calculated average with the wind direction from the first ensemble.

Parameters:

backup_method (str) – Backup method to use if the complex numbers approach has low confidence. “first_realization” uses the value of realization zero. “neighbourhood” (default) recalculates using the complex numbers approach with additional realizations extracted from neighbouring grid points from all available realizations.

__init__(backup_method='neighbourhood')[source]

Initialise class.

_abc_impl = <_abc_data object>
_reset()[source]

Empties working data objects

Return type:

None

calc_wind_dir_mean()[source]
Return type:

None

Find the mean wind direction using complex average which actually

signifies a point between all of the data points in POLAR coordinates - NOT the average DEGREE ANGLE.

Uses:
self.wdir_complex:

3D array or float - wind direction angles in degrees.

self.realization_axis:

Axis to collapse over.

Defines:
self.wdir_mean_complex:

3D array or float - wind direction angles as complex numbers collapsed along an axis using np.mean().

self.wdir_slice_mean:

3D array or float - wind direction angles in degrees collapsed along an axis using np.mean().

static complex_to_deg(complex_in)[source]

Converts complex to degrees.

The “np.angle” function returns negative numbers when the input is greater than 180. Therefore additional processing is needed to ensure that the angle is between 0-359.

Parameters:

complex_in (ndarray) – 3D array - wind direction angles in complex number form.

Return type:

ndarray

Returns:

3D array - wind direction in angle form

Raises:

TypeError – If complex_in is not an array.

static deg_to_complex(angle_deg, radius=1)[source]

Converts degrees to complex values.

The radius value can be used to weigh values - but it is set to 1 for now.

Parameters:
  • angle_deg (Union[ndarray, float]) – 3D array or float - wind direction angles in degrees.

  • radius (Union[ndarray, float]) – 3D array or float - radius value for each point, default=1.

Return type:

Union[ndarray, float]

Returns:

3D array or float - wind direction translated to complex numbers.

find_r_values()[source]

Find radius values from complex numbers.

Takes input wind direction in complex values and returns array containing r values using Pythagoras theorem.

Return type:

None

Uses:
self.wdir_mean_complex:

3D array or float - wind direction angles in complex numbers.

self.wdir_slice_mean:

3D array or float - mean wind direction angles in complex numbers.

Defines:
self.r_vals_slice:

Contains r values and inherits meta-data from self.wdir_slice_mean.

process(cube_ens_wdir)[source]

Create a cube containing the wind direction averaged over the ensemble realizations.

Parameters:

cube_ens_wdir (Cube) – Cube containing wind direction from multiple ensemble realizations.

Return type:

Cube

Returns:

  • Cube containing the wind direction averaged from the ensemble realizations.

Raises:

TypeError – If cube_wdir is not a cube.

wind_dir_decider(where_low_r, wdir_cube)[source]
If the wind direction is so widely scattered that the r value

is nearly zero then this indicates that the average wind direction is essentially meaningless. We therefore substitute this meaningless average wind direction value for the wind direction calculated from a larger sample by smoothing across a neighbourhood of points before rerunning the main technique. This is invoked rarely (1 : 100 000)

Parameters:
  • where_low_r (ndarray) – Array of boolean values. True where original wind direction estimate has low confidence. These points are replaced according to self.backup_method

  • wdir_cube (Cube) – Contains array of wind direction data (realization, y, x)

Return type:

None

Uses:
self.wdir_slice_mean:

Containing average wind direction angle (in degrees).

self.wdir_complex:

3D array - wind direction angles from ensembles (in complex).

self.r_vals_slice.data:

2D array - Radius taken from average complex wind direction angle.

self.r_thresh:

Any r value below threshold is regarded as meaningless.

self.realization_axis:

Axis to collapse over.

self.n_realizations:

Number of realizations available in the plugin. Used to set the neighbourhood radius as this is used to adjust the radius again in the neighbourhooding plugin.

Defines:
self.wdir_slice_mean.data:

2D array - Wind direction degrees where ambigious values have been replaced with data from first ensemble realization.