Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include AncillaryVariables and restructure Cube metadata. #3422

Merged
merged 7 commits into from
Oct 23, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* CF Ancillary Data are now supported in cubes.
30 changes: 23 additions & 7 deletions lib/iris/_concatenate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2013 - 2017, Met Office
# (C) British Crown Copyright 2013 - 2019, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -301,7 +301,8 @@ def _none_sort(item):
class _CubeSignature(object):
"""
Template for identifying a specific type of :class:`iris.cube.Cube` based
on its metadata, coordinates and cell_measures.
on its metadata and dimensional metadata, including: coordinates,
cell_measures and ancillary_variables.

"""
def __init__(self, cube):
Expand All @@ -322,6 +323,7 @@ def __init__(self, cube):
self.ndim = cube.ndim
self.scalar_coords = []
self.cell_measures_and_dims = cube._cell_measures_and_dims
self.ancillary_variables_and_dims = cube._ancillary_variables_and_dims
self.dim_mapping = []

# Determine whether there are any anonymous cube dimensions.
Expand Down Expand Up @@ -415,6 +417,8 @@ def match(self, other, error_on_mismatch):
- dimensions metadata
- aux coords metadata
- scalar coords
- cell measures
- ancillary variables
- attributes
- dtype

Expand Down Expand Up @@ -471,6 +475,14 @@ def match(self, other, error_on_mismatch):
self.cell_measures_and_dims,
other.cell_measures_and_dims))

# Check ancillary_variables_and_dims
if self.ancillary_variables_and_dims != \
other.ancillary_variables_and_dims:
msgs.append(msg_template.format(
'AncillaryVariables', '',
self.ancillary_variables_and_dims,
other.ancillary_variables_and_dims))

match = not bool(msgs)
if error_on_mismatch and not match:
raise iris.exceptions.ConcatenateError(msgs)
Expand Down Expand Up @@ -670,11 +682,15 @@ def concatenate(self):
kwargs = cube_signature.defn._asdict()
new_cm_and_dims = [(deepcopy(cm), dims) for cm, dims
in self._cube._cell_measures_and_dims]
cube = iris.cube.Cube(data,
dim_coords_and_dims=dim_coords_and_dims,
aux_coords_and_dims=aux_coords_and_dims,
cell_measures_and_dims=new_cm_and_dims,
**kwargs)
new_av_and_dims = [(deepcopy(av), dims) for av, dims
in self._cube._ancillary_variables_and_dims]
cube = iris.cube.Cube(
data,
dim_coords_and_dims=dim_coords_and_dims,
aux_coords_and_dims=aux_coords_and_dims,
cell_measures_and_dims=new_cm_and_dims,
ancillary_variables_and_dims=new_av_and_dims,
**kwargs)
else:
# There are no other source-cubes to concatenate
# with this proto-cube.
Expand Down
21 changes: 18 additions & 3 deletions lib/iris/_merge.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2010 - 2017, Met Office
# (C) British Crown Copyright 2010 - 2019, Met Office
#
# This file is part of Iris.
#
Expand Down Expand Up @@ -315,7 +315,8 @@ class _CoordSignature(namedtuple('CoordSignature',

class _CubeSignature(namedtuple('CubeSignature',
['defn', 'data_shape', 'data_type',
'cell_measures_and_dims'])):
'cell_measures_and_dims',
'ancillary_variables_and_dims'])):
"""
Criterion for identifying a specific type of :class:`iris.cube.Cube`
based on its metadata.
Expand All @@ -334,6 +335,9 @@ class _CubeSignature(namedtuple('CubeSignature',
* cell_measures_and_dims:
A list of cell_measures and dims for the cube.

* ancillary_variables_and_dims:
A list of ancillary_variables and dims for the cube.

"""

__slots__ = ()
Expand Down Expand Up @@ -405,6 +409,9 @@ def match(self, other, error_on_mismatch):
msgs.append(msg.format(self.data_type, other.data_type))
if (self.cell_measures_and_dims != other.cell_measures_and_dims):
msgs.append('cube.cell_measures differ')
if (self.ancillary_variables_and_dims !=
other.ancillary_variables_and_dims):
msgs.append('cube.ancillary_variables differ')

match = not bool(msgs)
if error_on_mismatch and not match:
Expand Down Expand Up @@ -1134,6 +1141,10 @@ def __init__(self, cube):
# they are checked and preserved through merge
self._cell_measures_and_dims = cube._cell_measures_and_dims

# ancillary_variables are not merge candidates
# they are checked and preserved through merge
self._ancillary_variables_and_dims = cube._ancillary_variables_and_dims

def _report_duplicate(self, nd_indexes, group_by_nd_index):
# Find the first offending source-cube with duplicate metadata.
index = [group_by_nd_index[nd_index][1]
Expand Down Expand Up @@ -1483,10 +1494,13 @@ def _get_cube(self, data):

cms_and_dims = [(deepcopy(cm), dims)
for cm, dims in self._cell_measures_and_dims]
av_and_dims = [(deepcopy(av), dims)
for av, dims in self._ancillary_variables_and_dims]
cube = iris.cube.Cube(data,
dim_coords_and_dims=dim_coords_and_dims,
aux_coords_and_dims=aux_coords_and_dims,
cell_measures_and_dims=cms_and_dims,
ancillary_variables_and_dims=av_and_dims,
**kwargs)

# Add on any aux coord factories.
Expand Down Expand Up @@ -1607,7 +1621,8 @@ def _build_signature(self, cube):
"""

return _CubeSignature(cube.metadata, cube.shape,
cube.dtype, cube._cell_measures_and_dims)
cube.dtype, cube._cell_measures_and_dims,
cube._ancillary_variables_and_dims)

def _add_cube(self, cube, coord_payload):
"""Create and add the source-cube skeleton to the ProtoCube."""
Expand Down
Loading