improver.wind_calculations.wind_direction module

Module containing wind direction averaging plugins.

class improver.wind_calculations.wind_direction.WindDirection(backup_method='neighbourhood')[source]

Bases: improver.BasePlugin

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.

  6. Calculate the confidence measure of the wind direction.

Step 6 still needs more development so it is only included in the code as a placeholder.

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_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 213
_abc_registry = <_weakrefset.WeakSet object>
_reset()[source]

Empties working data objects

calc_confidence_measure()[source]

Find confidence measure of polar numbers.

The average wind direction complex values represent the midpoint between the different values and so have r values between 0-1.

  1. From self.wdir_slice_mean - create a new set of complex values. Therefore they will have the same angle but r is fixed as r=1.

  2. Find the distance between the mean point and all the ensemble realization wind direction complex values.

  3. Find the average distance between the mean point and the wind direction values. Large average distance == low confidence.

  4. A confidence value that is between 1 for confident (small spread in ensemble realizations) and 0 for no-confidence. Set to 0 if r value is below threshold as any r value is regarded as meaningless.

Uses:
self.wdir_complex (numpy.ndarray):

3D array - wind direction angles in complex numbers.

self.wdir_slice_mean (iris.cube.Cube):

Contains average wind direction in angles.

self.realization_axis (int):

Axis to collapse over.

self.r_vals_slice.data (numpy.ndarray):

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

self.r_thresh (float):

Any r value below threshold is regarded as meaningless.

Defines:
self.confidence_slice (iris.cube.Cube):

Contains the average distance from mean normalised - used as a confidence value. Inherits meta-data from self.wdir_slice_mean

calc_wind_dir_mean()[source]
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 (numpy.ndarray or float):

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

self.realization_axis (int):

Axis to collapse over.

Defines:
self.wdir_mean_complex (numpy.ndarray or float):

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

self.wdir_slice_mean (numpy.ndarray or float):

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 (numpy.ndarray) – 3D array - wind direction angles in complex number form.

Returns

3D array - wind direction in angle form

Return type

numpy.ndarray

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 (numpy.ndarray or float) – 3D array or float - wind direction angles in degrees.

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

Returns

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

Return type

numpy.ndarray or float

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.

Uses:
self.wdir_mean_complex (numpy.ndarray or float):

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

self.wdir_slice_mean (iris.cube.Cube):

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

Defines:
self.r_vals_slice (iris.cube.Cube):

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 (iris.cube.Cube) – Cube containing wind direction from multiple ensemble realizations.

Returns

Cube containing the wind direction averaged from the

ensemble realizations.

cube_r_vals (numpy.ndarray):

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

cube_confidence_measure (numpy.ndarray):

3D array - The average distance from mean normalised - used as a confidence value.

Return type

iris.cube.Cube

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 (numpy.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 (iris.cube.Cube) – Contains array of wind direction data (realization, y, x)

Uses:
self.wdir_slice_mean (iris.cube.Cube):

Containing average wind direction angle (in degrees).

self.wdir_complex (numpy.ndarray):

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

self.r_vals_slice.data (numpy.ndarray):

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

self.r_thresh (float):

Any r value below threshold is regarded as meaningless.

self.realization_axis (int):

Axis to collapse over.

self.n_realizations (int):

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 (numpy.ndarray):

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