Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 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 - 2016, Met Office
# (C) British Crown Copyright 2010 - 2017, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -2246,6 +2246,10 @@ def is_valid_packspec(p):

conventions = CF_CONVENTIONS_VERSION

# Prioritise cube attributes conventions over the default.
if 'Conventions' in cube.attributes:
conventions = cube.attributes['Conventions']
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morwenna-01 Note that, the Conventions override requires to be applied here, otherwise the following cf_patch_conventions patching will fail in our tests ...

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bjlittle Sorry. As you can tell I'm new at this. Please tell me what I should do now.
It looks like I've got travis-ci working.
I'm guessing I should have done git pull or something.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morwenna-01 No worries ... I think that I can resolve this from my side. Let me try ...


# Perform a CF patch of the conventions attribute.
cf_profile_available = (iris.site_configuration.get('cf_profile') not
in [None, False])
Expand All @@ -2260,12 +2264,7 @@ def is_valid_packspec(p):
warnings.warn(msg)

# Add conventions attribute.
if (cube.attributes.has_key('Conventions')):
msg = 'Keeping conventions from original netcdf file'
warnings.warn(msg)
sman.update_global_attributes(Conventions=cube.attributes.get('Conventions'))
else:
sman.update_global_attributes(Conventions=conventions)
sman.update_global_attributes(Conventions=conventions)


def _no_unlim_dep_warning():
Expand Down
32 changes: 24 additions & 8 deletions lib/iris/tests/integration/test_netcdf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2014 - 2016, Met Office
# (C) British Crown Copyright 2014 - 2017, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -179,22 +179,38 @@ def update(config):


class TestConventionsAttributes(tests.IrisTest):
def test_patching_conventions_attribute(self):
# Ensure that user defined conventions are wiped and those which are
def test_patching_conventions_attribute_user_existing(self):
# Ensure that user defined conventions pass-thru and those which are
# saved patched through site_config can be loaded without an exception
# being raised.
conventions = 'some user defined conventions'
cube = Cube([1.0], standard_name='air_temperature', units='K',
attributes={'Conventions':
'some user defined conventions'})
attributes=dict(Conventions=conventions))

# Patch the site configuration dictionary.
with _patch_site_configuration(), self.temp_filename('.nc') as nc_path:
iris.save(cube, nc_path)
res = iris.load_cube(nc_path)

self.assertEqual(res.attributes['Conventions'],
'{}, {}, {}'.format(CF_CONVENTIONS_VERSION,
'convention1', 'convention2'))
expected = '{}, {}, {}'.format(conventions,
'convention1',
'convention2')
self.assertEqual(res.attributes['Conventions'], expected)

def test_patching_conventions_attribute_user_missing(self):
# Ensure that conventions which are saved patched through site_config
# can be loaded without an exception being raised.
cube = Cube([1.0], standard_name='air_temperature', units='K')

# Patch the site configuration dictionary.
with _patch_site_configuration(), self.temp_filename('.nc') as nc_path:
iris.save(cube, nc_path)
res = iris.load_cube(nc_path)

expected = '{}, {}, {}'.format(CF_CONVENTIONS_VERSION,
'convention1',
'convention2')
self.assertEqual(res.attributes['Conventions'], expected)


class TestLazySave(tests.IrisTest):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube long_name="Precipitation" standard_name="precipitation_flux" units="kg m-2 s-1" var_name="pr">
<attributes>
<attribute name="Conventions" value="CF-1.5"/>
<attribute name="Conventions" value="CF-1.0"/>
<attribute name="NCO" value="4.1.0"/>
<attribute name="experiment" value="ER3"/>
<attribute name="history" value="Thu Nov 29 10:45:50 2012: /project/ukmo/rhel6/nco/bin/ncks -d time,0,3 new_rotPole_precipitation.nc small_rotPole_precipitation.nc"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ variables:
:history = "Thu Nov 29 10:45:50 2012: /project/ukmo/rhel6/nco/bin/ncks -d time,0,3 new_rotPole_precipitation.nc small_rotPole_precipitation.nc" ;
:institution = "DMI" ;
:source = "HIRHAM" ;
:Conventions = "CF-1.5" ;
:Conventions = "CF-1.0" ;
}
15 changes: 4 additions & 11 deletions lib/iris/tests/test_netcdf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2010 - 2016, Met Office
# (C) British Crown Copyright 2010 - 2017, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -699,13 +699,10 @@ def test_attributes(self):
# Should be global attributes.
aglobals = {'history': 'A long time ago...',
'title': 'Attribute test',
'foo': 'bar'}
'foo': 'bar',
'Conventions': 'TEST'}
for k, v in six.iteritems(aglobals):
self.cube.attributes[k] = v
# Should be overriden.
aover = {'Conventions': 'TEST'}
for k, v in six.iteritems(aover):
self.cube.attributes[k] = v
# Should be data varible attributes.
avars = {'standard_error_multiplier': 23,
'flag_masks': 'a',
Expand All @@ -724,11 +721,7 @@ def test_attributes(self):
if getattr(ds, gkey) != aglobals.get(gkey):
exceptions.append('{} != {}'.format(getattr(ds, gkey),
aglobals.get(gkey)))
# Should be overriden.
for okey in aover:
if getattr(ds, okey) == aover.get(okey):
exceptions.append('{} != {}'.format(getattr(ds, okey),
avars.get(okey)))

dv = ds['temp']
# Should be data varible attributes;
# except STASH -> um_stash_source.
Expand Down
21 changes: 16 additions & 5 deletions 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 - 2016, Met Office
# (C) British Crown Copyright 2014 - 2017, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -33,11 +33,9 @@


class Test_attributes(tests.IrisTest):
def test_custom_conventions(self):
# Ensure that we drop existing conventions attributes and replace with
# CF convention.
def test_default_conventions(self):
# Ensure that cube with missing conventions use default.
cube = Cube([0])
cube.attributes['Conventions'] = 'convention1 convention2'

with self.temp_filename('.nc') as nc_path:
save(cube, nc_path, 'NETCDF4')
Expand All @@ -46,6 +44,19 @@ def test_custom_conventions(self):
ds.close()
self.assertEqual(res, CF_CONVENTIONS_VERSION)

def test_custom_conventions(self):
# Ensure that existing conventions attributes pass-thru.
cube = Cube([0])
conventions = 'convention1 convention2'
cube.attributes['Conventions'] = conventions

with self.temp_filename('.nc') as nc_path:
save(cube, nc_path, 'NETCDF4')
ds = nc.Dataset(nc_path)
res = ds.getncattr('Conventions')
ds.close()
self.assertEqual(res, conventions)

def test_attributes_arrays(self):
# Ensure that attributes containing NumPy arrays can be equality
# checked and their cubes saved as appropriate.
Expand Down