What’s new in Iris 1.6

Release:1.6.1
Date:18th February 2014

This document explains the new/changed features of Iris in version 1.6. (View all changes.)

Iris 1.6 features

Showcase Feature - Back to the future ...

The new iris.FUTURE global variable is a iris.Future instance that controls the run-time behaviour of Iris.

By setting iris.FUTURE.cell_datetime_objects to True, a time reference coordinate will return datetime-like objects when invoked with iris.coords.Coord.cell() or iris.coords.Coord.cells().

>>> from iris.coords import DimCoord
>>> iris.FUTURE.cell_datetime_objects = True
>>> coord = DimCoord([1, 2, 3], 'time', units='hours since epoch')
>>> print([str(cell) for cell in coord.cells()])
['1970-01-01 01:00:00', '1970-01-01 02:00:00', '1970-01-01 03:00:00']

Note that, either a datetime.datetime or netcdftime.datetime object instance will be returned, depending on the calendar of the time reference coordinate.

This capability permits the ability to express time constraints more naturally when the cell represents a datetime-like object.

# Ignore the 1st of January.
iris.Constraint(time=lambda cell: cell.point.month != 1 and cell.point.day != 1)

Note that, iris.Future also supports a context manager which allows multiple sections of code to execute with different run-time behaviour.

>>> print(iris.FUTURE)
Future(cell_datetime_objects=False)
>>> with iris.FUTURE.context(cell_datetime_objects=True):
...     # Code that expects to deal with datetime-like objects.
...     print(iris.FUTURE)
...
Future(cell_datetime_objects=True)
>>> print(iris.FUTURE)
Future(cell_datetime_objects=False)

Showcase Feature - Partial date/time ...

The iris.time.PartialDateTime class provides the ability to perform comparisons with other datetime-like objects such as datetime.datetime or netcdftime.datetime.

The year, month, day, hour, minute, second and microsecond attributes of a iris.time.PartialDateTime object may be fully or partially specified for any given comparison.

This is particularly useful for time based constraints, whilst enabling the iris.FUTURE.cell_datetime_objects, see here for further details on this new release feature.

from iris.time import PartialDateTime

# Ignore the 1st of January.
iris.Constraint(time=lambda cell: cell != PartialDateTime(month=1, day=1))

# Constrain by a specific year.
iris.Constraint(time=PartialDateTime(year=2013))

Also see the User Guide Constraining on Time section for further commentary.

Bugs fixed

Incompatible changes

Deprecations

  • iris.cube.Cube.add_history() has been deprecated in favour of users modifying/creating the history metadata directly. This is because the automatic behaviour did not deliver a sufficiently complete, auditable history and often prevented the merging of cubes.
  • iris.util.broadcast_weights() has been deprecated and replaced by the new utility function iris.util.broadcast_to_shape().
  • Callback mechanism iris.run_callback has had its deprecation of return values revoked. The callback can now return cube instances as well as inplace changes to the cube.

New Contributors

Congratulations and thank you to felicityguest, jkettleb, kwilliams-mo and shoyer who all made their first contribution to Iris!


A new utility function to assist with caching

To assist with management of caching results to file, the new utility function iris.util.file_is_newer_than() may be used to easily determine whether the modification time of a specified cache file is newer than one or more other files.

Typically, the use of caching is a means to circumvent the cost of repeating time consuming processing, or to reap the benefit of fast-loading a pickled cube.

# Determine whether to load from the cache or source.
if iris.util.file_is_newer(cache_file, source_file):
    with open(cache_file, 'rb') as fh:
        cube = cPickle.load(fh)
else:
    cube = iris.load_cube(source_file)

    # Perhaps perform some intensive processing ...

    # Create the cube cache.
    with open(cache_file, 'wb') as fh:
        cPickle.dump(cube, fh)

The RMS aggregator supports weights

The iris.analysis.RMS aggregator has been extended to allow the use of weights using the new keyword argument weights.

For example, an RMS weighted cube collapse is performed as follows:

from iris.analysis import RMS
collapsed_cube = cube.collapsed('height', RMS, weights=weights)

Equalise cube attributes

To assist with iris.cube.Cube merging, the new experimental in-place function iris.experimental.equalise_cubes.equalise_attributes() ensures that a sequence of cubes contains a common set of iris.cube.Cube.attributes.

This attempts to smooth the merging process by ensuring that all candidate cubes have the same attributes.

Masking a collapsed result by missing-data tolerance

The result from collapsing masked cube data may now be completely masked by providing a mdtol missing-data tolerance keyword to iris.cube.Cube.collapsed().

This tolerance provides a threshold that will completely mask the collapsed result whenever the fraction of data to missing-data is less than or equal to the provided tolerance.

Promote a scalar coordinate

The new utility function iris.util.new_axis() creates a new cube with a new leading dimension of size unity. If a scalar coordinate is provided, then the scalar coordinate is promoted to be the dimension coordinate for the new leading dimension.

Note that, this function will load the data payload of the cube.

A new PEAK aggregator providing spline interpolation

The new iris.analysis.PEAK aggregator calculates the global peak value from a spline interpolation of the iris.cube.Cube data payload along a nominated coordinate axis.

For example, to calculate the peak time:

from iris.analysis import PEAK
collapsed_cube = cube.collapsed('time', PEAK)