iris.util

Miscellaneous utility functions.

In this module:

iris.util.timers

Provides multiple named timers, each composed of multiple named steps.

Deprecated since version 1.7.

Only one step is active at a time, so calling start(timer_name, step_name) will stop the current step and start the new one.

Example Usage:

from iris.util import timers

def little_func(param):

    timers.restart("little func", "init")
    init()

    timers.restart("little func", "main")
    main(param)

    timers.restart("little func", "cleanup")
    cleanup()

    timers.stop("little func")

def my_big_func():

    timers.start("big func", "input")
    input()

    timers.start("big func", "processing")
    little_func(123)
    little_func(456)

    timers.start("big func", "output")
    output()

    print(timers.stop("big func"))

    print(timers.get("little func"))

↑ top ↑

iris.util.approx_equal(a, b, max_absolute_error=1e-10, max_relative_error=1e-10)

Returns whether two numbers are almost equal, allowing for the finite precision of floating point numbers.

↑ top ↑

iris.util.array_equal(array1, array2)

Returns whether two arrays have the same shape and elements.

This provides the same functionality as numpy.array_equal() but with additional support for arrays of strings.

↑ top ↑

iris.util.as_compatible_shape(src_cube, target_cube)

Return a cube with added length one dimensions to match the dimensionality and dimension ordering of target_cube.

This function can be used to add the dimensions that have been collapsed, aggregated or sliced out, promoting scalar coordinates to length one dimension coordinates where necessary. It operates by matching coordinate metadata to infer the dimensions that need modifying, so the provided cubes must have coordinates with the same metadata (see iris.coords.CoordDefn).

Note

This function will load and copy the data payload of src_cube.

Args:

  • src_cube:

    An instance of iris.cube.Cube with missing dimensions.

  • target_cube:

    An instance of iris.cube.Cube with the desired dimensionality.

Returns:
A instance of iris.cube.Cube with the same dimensionality as target_cube but with the data and coordinates from src_cube suitably reshaped to fit.

↑ top ↑

iris.util.between(lh, rh, lh_inclusive=True, rh_inclusive=True)

Provides a convenient way of defining a 3 element inequality such as a < number < b.

Arguments:

  • lh

    The left hand element of the inequality

  • rh

    The right hand element of the inequality

Keywords:

  • lh_inclusive - boolean

    Affects the left hand comparison operator to use in the inequality. True for <= false for <. Defaults to True.

  • rh_inclusive - boolean

    Same as lh_inclusive but for right hand operator.

For example:

between_3_and_6 = between(3, 6)
for i in range(10):
   print(i, between_3_and_6(i))


between_3_and_6 = between(3, 6, rh_inclusive=False)
for i in range(10):
   print(i, between_3_and_6(i))

↑ top ↑

iris.util.broadcast_to_shape(array, shape, dim_map)

Broadcast an array to a given shape.

Each dimension of the array must correspond to a dimension in the given shape. Striding is used to repeat the array until it matches the desired shape, returning repeated views on the original array. If you need to write to the resulting array, make a copy first.

Args:

  • array (numpy.ndarray-like)

    An array to broadcast.

  • shape (list, tuple etc.):

    The shape the array should be broadcast to.

  • dim_map (list, tuple etc.):

    A mapping of the dimensions of array to their corresponding element in shape. dim_map must be the same length as the number of dimensions in array. Each element of dim_map corresponds to a dimension of array and its value provides the index in shape which the dimension of array corresponds to, so the first element of dim_map gives the index of shape that corresponds to the first dimension of array etc.

Examples:

Broadcasting an array of shape (2, 3) to the shape (5, 2, 6, 3) where the first dimension of the array corresponds to the second element of the desired shape and the second dimension of the array corresponds to the fourth element of the desired shape:

a = np.array([[1, 2, 3], [4, 5, 6]])
b = broadcast_to_shape(a, (5, 2, 6, 3), (1, 3))

Broadcasting an array of shape (48, 96) to the shape (96, 48, 12):

# a is an array of shape (48, 96)
result = broadcast_to_shape(a, (96, 48, 12), (1, 0))

↑ top ↑

iris.util.broadcast_weights(weights, array, dims)

Broadcast a weights array to the shape of another array.

Each dimension of the weights array must correspond to a dimension of the other array.

Deprecated since version 1.6: Please use broadcast_to_shape().

Args:

  • weights (numpy.ndarray-like):

    An array of weights to broadcast.

  • array (numpy.ndarray-like):

    An array whose shape is the target shape for weights.

  • dims (list tuple etc.):

    A sequence of dimension indices, specifying which dimensions of array are represented in weights. The order the dimensions are given in is not important, but the order of the dimensions in weights should be the same as the relative ordering of the corresponding dimensions in array. For example, if array is 4d with dimensions (ntime, nlev, nlat, nlon) and weights provides latitude-longitude grid weightings then dims could be set to [2, 3] or [3, 2] but weights must have shape (nlat, nlon) since the latitude dimension comes before the longitude dimension in array.

↑ top ↑

iris.util.clip_string(the_str, clip_length=70, rider='...')

Returns a clipped version of the string based on the specified clip length and whether or not any graceful clip points can be found.

If the string to be clipped is shorter than the specified clip length, the original string is returned.

If the string is longer than the clip length, a graceful point (a space character) after the clip length is searched for. If a graceful point is found the string is clipped at this point and the rider is added. If no graceful point can be found, then the string is clipped exactly where the user requested and the rider is added.

Args:

  • the_str

    The string to be clipped

  • clip_length

    The length in characters that the input string should be clipped to. Defaults to a preconfigured value if not specified.

  • rider

    A series of characters appended at the end of the returned string to show it has been clipped. Defaults to a preconfigured value if not specified.

Returns:
The string clipped to the required length with a rider appended. If the clip length was greater than the orignal string, the original string is returned unaltered.

↑ top ↑

iris.util.column_slices_generator(full_slice, ndims)

Given a full slice full of tuples, return a dictionary mapping old data dimensions to new and a generator which gives the successive slices needed to index correctly (across columns).

This routine deals with the special functionality for tuple based indexing e.g. [0, (3, 5), :, (1, 6, 8)] by first providing a slice which takes the non tuple slices out first i.e. [0, :, :, :] then subsequently iterates through each of the tuples taking out the appropriate slices i.e. [(3, 5), :, :] followed by [:, :, (1, 6, 8)]

This method was developed as numpy does not support the direct approach of [(3, 5), : , (1, 6, 8)] for column based indexing.

↑ top ↑

iris.util.create_temp_filename(suffix='')

Return a temporary file name.

Args:

  • suffix - Optional filename extension.

↑ top ↑

iris.util.delta(ndarray, dimension, circular=False)

Calculates the difference between values along a given dimension.

Args:

  • ndarray:

    The array over which to do the difference.

  • dimension:

    The dimension over which to do the difference on ndarray.

  • circular:

    If not False then return n results in the requested dimension with the delta between the last and first element included in the result otherwise the result will be of length n-1 (where n is the length of ndarray in the given dimension’s direction)

    If circular is numeric then the value of circular will be added to the last element of the given dimension if the last element is negative, otherwise the value of circular will be subtracted from the last element.

    The example below illustrates the process:

    original array              -180, -90,  0,    90
    delta (with circular=360):    90,  90, 90, -270+360
    

Note

The difference algorithm implemented is forward difference:

>>> import numpy as np
>>> import iris.util
>>> original = np.array([-180, -90, 0, 90])
>>> iris.util.delta(original, 0)
array([90, 90, 90])
>>> iris.util.delta(original, 0, circular=360)
array([90, 90, 90, 90])

↑ top ↑

iris.util.demote_dim_coord_to_aux_coord(cube, name_or_coord)

Demotes a dimension coordinate on the cube to an auxiliary coordinate.

The DimCoord is demoted to an auxiliary coordinate on the cube. The dimension of the cube that was associated with the DimCoord becomes anonymous. The class of the coordinate is left as DimCoord, it is not recast as an AuxCoord instance.

Args:

For example:

>>> print cube
air_temperature / (K)       (time: 12; latitude: 73; longitude: 96)
     Dimension coordinates:
          time                    x      -              -
          latitude                -      x              -
          longitude               -      -              x
     Auxiliary coordinates:
          year                    x      -              -
>>> demote_dim_coord_to_aux_coord(cube, 'time')
>>> print cube
air_temperature / (K)        (-- : 12; latitude: 73; longitude: 96)
     Dimension coordinates:
          latitude                -      x              -
          longitude               -      -              x
     Auxiliary coordinates:
          time                    x      -              -
          year                    x      -              -

↑ top ↑

iris.util.describe_diff(cube_a, cube_b, output_file=None)

Prints the differences that prevent compatibility between two cubes, as defined by iris.cube.Cube.is_compatible().

Args:

Note

Compatibility does not guarantee that two cubes can be merged. Instead, this function is designed to provide a verbose description of the differences in metadata between two cubes. Determining whether two cubes will merge requires additional logic that is beyond the scope of this function.

↑ top ↑

iris.util.ensure_array(a)

Deprecated since version 1.7.

↑ top ↑

iris.util.file_is_newer_than(result_path, source_paths)

Return whether the ‘result’ file has a later modification time than all of the ‘source’ files.

If a stored result depends entirely on known ‘sources’, it need only be re-built when one of them changes. This function can be used to test that by comparing file timestamps.

Args:

  • result_path (string):

    The filepath of a file containing some derived result data.

  • source_paths (string or iterable of strings):

    The path(s) to the original datafiles used to make the result. May include wildcards and ‘~’ expansions (like Iris load paths), but not URIs.

Returns:

True if all the sources are older than the result, else False.

If any of the file paths describes no existing files, an exception will be raised.

Note

There are obvious caveats to using file timestamps for this, as correct usage depends on how the sources might change. For example, a file could be replaced by one of the same name, but an older timestamp.

If wildcards and ‘~’ expansions are used, this introduces even more uncertainty, as then you cannot even be sure that the resulting list of file names is the same as the originals. For example, some files may have been deleted or others added.

Note

The result file may often be a pickle file. In that case, it also depends on the relevant module sources, so extra caution is required. Ideally, an additional check on iris.__version__ is advised.

↑ top ↑

iris.util.format_array(arr)

Returns the given array as a string, using the python builtin str function on a piecewise basis.

Useful for xml representation of arrays.

For customisations, use the numpy.core.arrayprint directly.

↑ top ↑

iris.util.guess_coord_axis(coord)

Returns a “best guess” axis name of the coordinate.

Heuristic categorisation of the coordinate into either label ‘T’, ‘Z’, ‘Y’, ‘X’ or None.

Args:

Returns:
‘T’, ‘Z’, ‘Y’, ‘X’, or None.

↑ top ↑

iris.util.is_regular(coord)

Determine if the given coord is regular.

↑ top ↑

iris.util.monotonic(array, strict=False, return_direction=False)

Return whether the given 1d array is monotonic.

Note that, the array must not contain missing data.

Kwargs:

  • strict (boolean)

    Flag to enable strict monotonic checking

  • return_direction (boolean)

    Flag to change return behaviour to return (monotonic_status, direction). Direction will be 1 for positive or -1 for negative. The direction is meaningless if the array is not monotonic.

Returns:

  • monotonic_status (boolean)

    Whether the array was monotonic.

    If the return_direction flag was given then the returned value will be:

    (monotonic_status, direction)

↑ top ↑

iris.util.new_axis(src_cube, scalar_coord=None)

Create a new axis as the leading dimension of the cube, promoting a scalar coordinate if specified.

Args:

  • src_cube (iris.cube.Cube)

    Source cube on which to generate a new axis.

Kwargs:

  • scalar_coord (iris.coord.Coord or ‘string’)

    Scalar coordinate to promote to a dimension coordinate.

Returns:
A new iris.cube.Cube instance with one extra leading dimension (length 1).

For example:

>>> cube.shape
(360, 360)
>>> ncube = iris.util.new_axis(cube, 'time')
>>> ncube.shape
(1, 360, 360)

↑ top ↑

iris.util.promote_aux_coord_to_dim_coord(cube, name_or_coord)

Promotes an AuxCoord on the cube to a DimCoord. This AuxCoord must be associated with a single cube dimension. If the AuxCoord is associated with a dimension that already has a DimCoord, that DimCoord gets demoted to an AuxCoord.

Args:

For example:

>>> print cube
air_temperature / (K)       (time: 12; latitude: 73; longitude: 96)
     Dimension coordinates:
          time                    x      -              -
          latitude                -      x              -
          longitude               -      -              x
     Auxiliary coordinates:
          year                    x      -              -
>>> promote_aux_coord_to_dim_coord(cube, 'year')
>>> print cube
air_temperature / (K)       (year: 12; latitude: 73; longitude: 96)
     Dimension coordinates:
          year                    x      -              -
          latitude                -      x              -
          longitude               -      -              x
     Auxiliary coordinates:
          time                    x      -              -

↑ top ↑

iris.util.regular_step(coord)

Return the regular step from a coord or fail.

↑ top ↑

iris.util.reverse(array, axes)

Reverse the array along the given axes.

Args:

  • array

    The array to reverse

  • axes

    A single value or array of values of axes to reverse

>>> import numpy as np
>>> a = np.arange(24).reshape(2, 3, 4)
>>> print(a)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
>>> print(reverse(a, 1))
[[[ 8  9 10 11]
  [ 4  5  6  7]
  [ 0  1  2  3]]

 [[20 21 22 23]
  [16 17 18 19]
  [12 13 14 15]]]
>>> print(reverse(a, [1, 2]))
[[[11 10  9  8]
  [ 7  6  5  4]
  [ 3  2  1  0]]

 [[23 22 21 20]
  [19 18 17 16]
  [15 14 13 12]]]

↑ top ↑

iris.util.rolling_window(a, window=1, step=1, axis=-1)

Make an ndarray with a rolling window of the last dimension

Args:

  • a
    : array_like

    Array to add rolling window to

Kwargs:

  • window
    : int

    Size of rolling window

  • step
    : int

    Size of step between rolling windows

  • axis
    : int

    Axis to take the rolling window over

Returns:

Array that is a view of the original array with an added dimension of the size of the given window at axis + 1.

Examples:

>>> x = np.arange(10).reshape((2, 5))
>>> rolling_window(x, 3)
array([[[0, 1, 2], [1, 2, 3], [2, 3, 4]],
       [[5, 6, 7], [6, 7, 8], [7, 8, 9]]])

Calculate rolling mean of last dimension:

>>> np.mean(rolling_window(x, 3), -1)
array([[ 1.,  2.,  3.],
       [ 6.,  7.,  8.]])

↑ top ↑

iris.util.squeeze(cube)

Removes any dimension of length one. If it has an associated DimCoord or AuxCoord, this becomes a scalar coord.

Args:

  • cube (iris.cube.Cube)

    Source cube to remove length 1 dimension(s) from.

Returns:
A new iris.cube.Cube instance without any dimensions of length 1.

For example:

>>> cube.shape
(1, 360, 360)
>>> ncube = iris.util.squeeze(cube)
>>> ncube.shape
(360, 360)

↑ top ↑

iris.util.unify_time_units(cubes)

Performs an in-place conversion of the time units of all time coords in the cubes in a given iterable. One common epoch is defined for each calendar found in the cubes to prevent units being defined with inconsistencies between epoch and calendar.

Each epoch is defined from the first suitable time coordinate found in the input cubes.

Arg: