Skip to content

Commit

Permalink
Merge pull request #1607 from marqh/ncunlimdep
Browse files Browse the repository at this point in the history
Ncunlimdep
  • Loading branch information
bjlittle committed Apr 8, 2015
2 parents b1d38ca + 2fcb45a commit 1318753
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 9 deletions.
3 changes: 3 additions & 0 deletions docs/iris/src/whatsnew/1.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ Deprecations
============
* The original GRIB loader has been deprecated and replaced with a new
template-based GRIB loader.
* Deprecated default NetCDF save behaviour of assigning the outermost
dimension to be unlimited. Switch to the new behaviour with no auto
assignment by setting :data:`iris.FUTURE.netcdf_no_unlimited` to True.

Documentation Changes
=====================
Expand Down
16 changes: 11 additions & 5 deletions lib/iris/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class Future(threading.local):
"""Run-time configuration controller."""

def __init__(self, cell_datetime_objects=False, netcdf_promote=False,
strict_grib_load=False):
strict_grib_load=False, netcdf_no_unlimited=False):
"""
A container for run-time options controls.
Expand Down Expand Up @@ -170,16 +170,22 @@ def __init__(self, cell_datetime_objects=False, netcdf_promote=False,
encounters a GRIB message which uses a template not supported
by the conversion.
The option `netcdf_no_unlimited`, when True, changes the
behaviour of the netCDF saver, such that no dimensions are set to
unlimited. The current default is that the leading dimension is
unlimited unless otherwise specified.
"""
self.__dict__['cell_datetime_objects'] = cell_datetime_objects
self.__dict__['netcdf_promote'] = netcdf_promote
self.__dict__['strict_grib_load'] = strict_grib_load
self.__dict__['netcdf_no_unlimited'] = netcdf_no_unlimited

def __repr__(self):
return ('Future(cell_datetime_objects={}, netcdf_promote={}, '
'strict_grib_load={})'.format(self.cell_datetime_objects,
self.netcdf_promote,
self.strict_grib_load))
msg = ('Future(cell_datetime_objects={}, netcdf_promote={}, '
'strict_grib_load={}, netcdf_no_unlimited={})')
return msg.format(self.cell_datetime_objects, self.netcdf_promote,
self.strict_grib_load, self.netcdf_no_unlimited)

def __setattr__(self, name, value):
if name not in self.__dict__:
Expand Down
40 changes: 38 additions & 2 deletions lib/iris/fileformats/netcdf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2010 - 2014, Met Office
# (C) British Crown Copyright 2010 - 2015, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -724,7 +724,20 @@ def write(self, cube, local_keys=None, unlimited_dimensions=None,
`chunksizes` and `endian` keywords are silently ignored for netCDF
3 files that do not use HDF5.
.. deprecated:: 1.8.0
NetCDF default saving behaviour currently assigns the outermost
dimension as unlimited. This behaviour is to be deprecated, in
favour of no automatic assignment. To switch to the new behaviour,
set `iris.FUTURE.netcdf_no_unlimited` to True.
"""
if unlimited_dimensions is None:
if iris.FUTURE.netcdf_no_unlimited:
unlimited_dimensions = []
else:
_no_unlim_dep_warning()

cf_profile_available = (iris.site_configuration.get('cf_profile') not
in [None, False])
if cf_profile_available:
Expand Down Expand Up @@ -822,7 +835,8 @@ def _create_cf_dimensions(self, cube, dimension_names,
"""
unlimited_dim_names = []
if unlimited_dimensions is None:
if (unlimited_dimensions is None and
not iris.FUTURE.netcdf_no_unlimited):
if dimension_names:
unlimited_dim_names.append(dimension_names[0])
else:
Expand Down Expand Up @@ -1645,7 +1659,20 @@ def save(cube, filename, netcdf_format='NETCDF4', local_keys=None,
NetCDF Context manager (:class:`~Saver`).
.. deprecated:: 1.8.0
NetCDF default saving behaviour currently assigns the outermost
dimensions to unlimited. This behaviour is to be deprecated, in
favour of no automatic assignment. To switch to the new behaviour,
set `iris.FUTURE.netcdf_no_unlimited` to True.
"""
if unlimited_dimensions is None:
if iris.FUTURE.netcdf_no_unlimited:
unlimited_dimensions = []
else:
_no_unlim_dep_warning()

if isinstance(cube, iris.cube.Cube):
cubes = iris.cube.CubeList()
cubes.append(cube)
Expand Down Expand Up @@ -1698,3 +1725,12 @@ def save(cube, filename, netcdf_format='NETCDF4', local_keys=None,

# Add conventions attribute.
sman.update_global_attributes(Conventions=conventions)


def _no_unlim_dep_warning():
msg = ('NetCDF default saving behaviour currently assigns the '
'outermost dimensions to unlimited. This behaviour is to be '
'deprecated, in favour of no automatic assignment. To switch '
'to the new behaviour, set iris.FUTURE.netcdf_no_unlimited to '
'True.')
warnings.warn(msg)
22 changes: 21 additions & 1 deletion lib/iris/tests/unit/fileformats/netcdf/test_save.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2014, Met Office
# (C) British Crown Copyright 2014 - 2015, Met Office
#
# This file is part of Iris.
#
Expand All @@ -25,8 +25,10 @@
import netCDF4 as nc
import numpy as np

import iris
from iris.cube import Cube
from iris.fileformats.netcdf import save, CF_CONVENTIONS_VERSION
from iris.tests.stock import lat_lon_cube


class Test_attributes(tests.IrisTest):
Expand Down Expand Up @@ -57,5 +59,23 @@ def test_attributes_arrays(self):
self.assertArrayEqual(res, np.arange(2))


class Test_unlimited_dims(tests.IrisTest):
def test_no_unlimited_default(self):
cube = lat_lon_cube()
with iris.FUTURE.context(netcdf_no_unlimited=False):
with self.temp_filename('foo.nc') as nc_out:
save(cube, nc_out)
ds = nc.Dataset(nc_out)
self.assertTrue(ds.dimensions['latitude'].isunlimited())

def test_no_unlimited_future_default(self):
cube = lat_lon_cube()
with iris.FUTURE.context(netcdf_no_unlimited=True):
with self.temp_filename('foo.nc') as nc_out:
save(cube, nc_out)
ds = nc.Dataset(nc_out)
self.assertFalse(ds.dimensions['latitude'].isunlimited())


if __name__ == "__main__":
tests.main()
8 changes: 7 additions & 1 deletion lib/iris/tests/unit/test_Future.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2013 - 2014, Met Office
# (C) British Crown Copyright 2013 - 2015, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -26,6 +26,12 @@


class Test___setattr__(tests.IrisTest):
def test_valid_netcdf_no_unlimited(self):
future = Future()
new_value = not future.netcdf_no_unlimited
future.netcdf_no_unlimited = new_value
self.assertEqual(future.netcdf_no_unlimited, new_value)

def test_valid_cell_datetime_objects(self):
future = Future()
new_value = not future.cell_datetime_objects
Expand Down

0 comments on commit 1318753

Please sign in to comment.