diff --git a/lib/iris/_merge.py b/lib/iris/_merge.py
index 15a6933c49..14d17da6ee 100644
--- a/lib/iris/_merge.py
+++ b/lib/iris/_merge.py
@@ -1,4 +1,4 @@
-# (C) British Crown Copyright 2010 - 2012, Met Office
+# (C) British Crown Copyright 2010 - 2013, Met Office
#
# This file is part of Iris.
#
@@ -582,7 +582,7 @@ def _is_dependent(dependent, independent, positions, function_mapping=None):
return valid
-def _derive_separable_consistent_groups(relation_matrix, separable_group):
+def _derive_consistent_groups(relation_matrix, separable_group):
"""
Determine the largest combinations of candidate dimensions within the
separable group that are self consistently separable from one another.
@@ -656,7 +656,7 @@ def _build_separable_group(space, group, separable_consistent_groups, positions,
participates in a functional relationship.
Returns:
- None.
+ Boolean.
"""
valid = False
@@ -683,8 +683,8 @@ def _build_separable_group(space, group, separable_consistent_groups, positions,
if valid:
space.update({name: None for name in independent})
space.update({name: tuple(independent) for name in dependent})
- else:
- raise iris.exceptions.NotYetImplementedError('No functional relationship between separable and inseparable candidate dimensions.')
+
+ return valid
def _build_inseparable_group(space, group, positions, function_matrix):
@@ -820,7 +820,8 @@ def derive_space(groups, relation_matrix, positions, function_matrix=None):
participates in a functional relationship.
Returns:
- A space dictionary describing the relationship between each candidate dimension.
+ A space dictionary describing the relationship between each
+ candidate dimension.
"""
space = {}
@@ -829,22 +830,33 @@ def derive_space(groups, relation_matrix, positions, function_matrix=None):
separable_group = _derive_separable_group(relation_matrix, group)
if len(group) == 1 and not separable_group:
- # This single candidate dimension is separable from all other candidate dimensions
- # in the group, therefore it is a genuine dimension of the space.
+ # This single candidate dimension is separable from all other
+ # candidate dimensions in the group, therefore it is a genuine
+ # dimension of the space.
space.update({name: None for name in group})
elif separable_group:
- # Determine the largest combination of the candidate dimensions
+ # Determine the largest combination of the candidate dimensions
# in the separable group that are consistently separable.
- separable_consistent_groups = _derive_separable_consistent_groups(relation_matrix, separable_group)
- _build_separable_group(space, group, separable_consistent_groups, positions, function_matrix)
+ consistent_groups = _derive_consistent_groups(relation_matrix,
+ separable_group)
+ if not _build_separable_group(space, group, consistent_groups,
+ positions, function_matrix):
+ # There is no relationship between any of the candidate
+ # dimensions in the separable group, so merge them together
+ # into a new combined dimesion of the space.
+ _build_combination_group(space, group,
+ positions, function_matrix)
else:
# Determine whether there is a scalar relationship between one of
- # the candidate dimensions and each of the other candidate dimensions
- # in this inseparable group.
- if not _build_inseparable_group(space, group, positions, function_matrix):
- # There is no relationship between any of the candidate dimensions in this
- # inseparable group, so merge them together into a new combined dimension of the space.
- _build_combination_group(space, group, positions, function_matrix)
+ # the candidate dimensions and each of the other candidate
+ # dimensions in this inseparable group.
+ if not _build_inseparable_group(space, group,
+ positions, function_matrix):
+ # There is no relationship between any of the candidate
+ # dimensions in this inseparable group, so merge them together
+ # into a new combined dimension of the space.
+ _build_combination_group(space, group,
+ positions, function_matrix)
return space
@@ -1064,7 +1076,8 @@ def _define_space(self, space, positions, indexes, function_matrix):
dim_by_name[name] = len(self._shape)
self._nd_names.append(name)
self._shape.append(len(cells))
- self._cache_by_name[name] = {cell:index for index, cell in enumerate(cells)}
+ self._cache_by_name[name] = {cell: index for index, cell \
+ in enumerate(cells)}
else:
# TODO: Consider appropriate sort order (ascending, decending) i.e. use CF positive attribute.
cells = sorted(indexes[name])
@@ -1086,7 +1099,8 @@ def _define_space(self, space, positions, indexes, function_matrix):
else:
self._dim_templates.append(_Template(dim, points, bounds, kwargs))
self._shape.append(len(cells))
- self._cache_by_name[name] = {cell:index for index, cell in enumerate(cells)}
+ self._cache_by_name[name] = {cell: index for index, cell \
+ in enumerate(cells)}
# Second pass - Build the auxiliary coordinate templates for the space.
for name in names:
@@ -1202,10 +1216,10 @@ def _build_coordinates(self):
# Build the dimension coordinates.
for template in self._dim_templates:
- # sometimes its not possible to build a dim coord (for example,
- # if your bounds are not monotonic, so try building the coordinate,
- # and if it fails make the coordinate into a aux coord. This will
- # ultimately make an anonymous dimension.
+ # Sometimes it's not possible to build a dim coordinate e.g.
+ # the bounds are not monotonic, so try building the coordinate,
+ # and if it fails make the coordinate into an auxiliary coordinate.
+ # This will ultimately make an anonymous dimension.
try:
coord = iris.coords.DimCoord(template.points,
bounds=template.bounds,
@@ -1214,10 +1228,10 @@ def _build_coordinates(self):
except ValueError:
self._aux_templates.append(template)
- # there is the potential that there are still anonymous dimensions
- # get a list of the dimensions which are not anonymous at this stage
- covered_dims = [dim_coord_and_dim.dims
- for dim_coord_and_dim in dim_coords_and_dims]
+ # There is the potential that there are still anonymous dimensions.
+ # Get a list of the dimensions which are not anonymous at this stage.
+ covered_dims = [dim_coord_and_dim.dims \
+ for dim_coord_and_dim in dim_coords_and_dims]
# Build the auxiliary coordinates.
for template in self._aux_templates:
@@ -1271,6 +1285,10 @@ def _add_cube(self, cube, coord_payload):
"""Create and add the source-cube skeleton to the ProtoCube."""
skeleton = _Skeleton(coord_payload.scalar.values, cube._data)
+ # Attempt to do something sensible with mixed scalar dtypes.
+ for i, metadata in enumerate(coord_payload.scalar.metadata):
+ if metadata.points_dtype > self._coord_metadata[i].points_dtype:
+ self._coord_metadata[i] = metadata
self._skeletons.append(skeleton)
def _extract_coord_payload(self, cube):
@@ -1301,10 +1319,14 @@ def _extract_coord_payload(self, cube):
hint_dict = {name: i for i, name in zip(range(len(self._hints), 0, -1), self._hints[::-1])}
# Coordinate axis ordering dictionary.
axis_dict = {'T': 0, 'Z': 1, 'Y': 2, 'X': 3}
- # Coordinate sort function - by coordinate hint, then by guessed coordinate axis, then
- # by coordinate definition, in ascending order.
- key_func = lambda coord: (hint_dict.get(coord.name(), len(hint_dict) + 1),
- axis_dict.get(iris.util.guess_coord_axis(coord), len(axis_dict) + 1),
+ # Coordinate sort function.
+ key_func = lambda coord: (not np.issubdtype(coord.points.dtype,
+ np.number),
+ not isinstance(coord, iris.coords.DimCoord),
+ hint_dict.get(coord.name(),
+ len(hint_dict) + 1),
+ axis_dict.get(iris.util.guess_coord_axis(coord),
+ len(axis_dict) + 1),
coord._as_defn())
# Order the coordinates by hints, axis, and definition.
diff --git a/lib/iris/etc/pp_rules.txt b/lib/iris/etc/pp_rules.txt
index 490e0d45cf..f63172d4af 100644
--- a/lib/iris/etc/pp_rules.txt
+++ b/lib/iris/etc/pp_rules.txt
@@ -1,4 +1,4 @@
-# (C) British Crown Copyright 2010 - 2012, Met Office
+# (C) British Crown Copyright 2010 - 2013, Met Office
#
# This file is part of Iris.
#
@@ -356,7 +356,7 @@ f.lbvc == 65
THEN
#need orography field to calculate 3D array height coord
###, coord_system=HybridHeightCS(Reference('orography')))
-CoordAndDims(AuxCoord(f.lblev, standard_name='model_level_number', attributes={'positive': 'up'}))
+CoordAndDims(DimCoord(f.lblev, standard_name='model_level_number', attributes={'positive': 'up'}))
CoordAndDims(DimCoord(f.blev, long_name='level_height', units='m', bounds=[f.brlev, f.brsvd[0]], attributes={'positive': 'up'}))
CoordAndDims(AuxCoord(f.bhlev, long_name='sigma', bounds=[f.bhrlev, f.brsvd[1]]))
Factory(HybridHeightFactory, [{'long_name': 'level_height'}, {'long_name': 'sigma'}, Reference('orography')])
diff --git a/lib/iris/tests/results/file_load/theta_levels.cml b/lib/iris/tests/results/file_load/theta_levels.cml
index b597015916..68b22e83b5 100644
--- a/lib/iris/tests/results/file_load/theta_levels.cml
+++ b/lib/iris/tests/results/file_load/theta_levels.cml
@@ -30,11 +30,11 @@
-
+
-
+
@@ -80,11 +80,11 @@
-
+
-
+
@@ -130,11 +130,11 @@
-
+
-
+
@@ -180,11 +180,11 @@
-
+
-
+
@@ -230,11 +230,11 @@
-
+
-
+
@@ -280,11 +280,11 @@
-
+
-
+
@@ -330,11 +330,11 @@
-
+
-
+
@@ -380,11 +380,11 @@
-
+
-
+
@@ -430,11 +430,11 @@
-
+
-
+
@@ -480,11 +480,11 @@
-
+
-
+
@@ -530,11 +530,11 @@
-
+
-
+
@@ -580,11 +580,11 @@
-
+
-
+
@@ -630,11 +630,11 @@
-
+
-
+
@@ -680,11 +680,11 @@
-
+
-
+
@@ -730,11 +730,11 @@
-
+
-
+
@@ -780,11 +780,11 @@
-
+
-
+
@@ -830,11 +830,11 @@
-
+
-
+
@@ -880,11 +880,11 @@
-
+
-
+
@@ -930,11 +930,11 @@
-
+
-
+
@@ -980,11 +980,11 @@
-
+
-
+
@@ -1030,11 +1030,11 @@
-
+
-
+
@@ -1080,11 +1080,11 @@
-
+
-
+
@@ -1130,11 +1130,11 @@
-
+
-
+
@@ -1180,11 +1180,11 @@
-
+
-
+
@@ -1230,11 +1230,11 @@
-
+
-
+
@@ -1280,11 +1280,11 @@
-
+
-
+
@@ -1330,11 +1330,11 @@
-
+
-
+
@@ -1380,11 +1380,11 @@
-
+
-
+
@@ -1430,11 +1430,11 @@
-
+
-
+
@@ -1480,11 +1480,11 @@
-
+
-
+
@@ -1530,11 +1530,11 @@
-
+
-
+
@@ -1580,11 +1580,11 @@
-
+
-
+
@@ -1630,11 +1630,11 @@
-
+
-
+
@@ -1680,11 +1680,11 @@
-
+
-
+
@@ -1730,11 +1730,11 @@
-
+
-
+
@@ -1780,11 +1780,11 @@
-
+
-
+
@@ -1830,11 +1830,11 @@
-
+
-
+
@@ -1880,11 +1880,11 @@
-
+
-
+
diff --git a/lib/iris/tests/results/file_load/u_wind_levels.cml b/lib/iris/tests/results/file_load/u_wind_levels.cml
index 2bfdd01cab..b51d171d15 100644
--- a/lib/iris/tests/results/file_load/u_wind_levels.cml
+++ b/lib/iris/tests/results/file_load/u_wind_levels.cml
@@ -31,11 +31,11 @@
-
+
-
+
@@ -82,11 +82,11 @@
-
+
-
+
@@ -133,11 +133,11 @@
-
+
-
+
@@ -184,11 +184,11 @@
-
+
-
+
@@ -235,11 +235,11 @@
-
+
-
+
@@ -286,11 +286,11 @@
-
+
-
+
@@ -337,11 +337,11 @@
-
+
-
+
@@ -388,11 +388,11 @@
-
+
-
+
@@ -439,11 +439,11 @@
-
+
-
+
@@ -490,11 +490,11 @@
-
+
-
+
@@ -541,11 +541,11 @@
-
+
-
+
@@ -592,11 +592,11 @@
-
+
-
+
@@ -643,11 +643,11 @@
-
+
-
+
@@ -694,11 +694,11 @@
-
+
-
+
@@ -745,11 +745,11 @@
-
+
-
+
@@ -796,11 +796,11 @@
-
+
-
+
@@ -847,11 +847,11 @@
-
+
-
+
@@ -898,11 +898,11 @@
-
+
-
+
@@ -949,11 +949,11 @@
-
+
-
+
@@ -1000,11 +1000,11 @@
-
+
-
+
@@ -1051,11 +1051,11 @@
-
+
-
+
@@ -1102,11 +1102,11 @@
-
+
-
+
@@ -1153,11 +1153,11 @@
-
+
-
+
@@ -1204,11 +1204,11 @@
-
+
-
+
@@ -1255,11 +1255,11 @@
-
+
-
+
@@ -1306,11 +1306,11 @@
-
+
-
+
@@ -1357,11 +1357,11 @@
-
+
-
+
@@ -1408,11 +1408,11 @@
-
+
-
+
@@ -1459,11 +1459,11 @@
-
+
-
+
@@ -1510,11 +1510,11 @@
-
+
-
+
@@ -1561,11 +1561,11 @@
-
+
-
+
@@ -1612,11 +1612,11 @@
-
+
-
+
@@ -1663,11 +1663,11 @@
-
+
-
+
@@ -1714,11 +1714,11 @@
-
+
-
+
@@ -1765,11 +1765,11 @@
-
+
-
+
@@ -1816,11 +1816,11 @@
-
+
-
+
@@ -1867,11 +1867,11 @@
-
+
-
+
@@ -1918,11 +1918,11 @@
-
+
-
+
diff --git a/lib/iris/tests/results/file_load/v_wind_levels.cml b/lib/iris/tests/results/file_load/v_wind_levels.cml
index 0ffb6ca612..a37f8621d0 100644
--- a/lib/iris/tests/results/file_load/v_wind_levels.cml
+++ b/lib/iris/tests/results/file_load/v_wind_levels.cml
@@ -31,11 +31,11 @@
-
+
-
+
@@ -82,11 +82,11 @@
-
+
-
+
@@ -133,11 +133,11 @@
-
+
-
+
@@ -184,11 +184,11 @@
-
+
-
+
@@ -235,11 +235,11 @@
-
+
-
+
@@ -286,11 +286,11 @@
-
+
-
+
@@ -337,11 +337,11 @@
-
+
-
+
@@ -388,11 +388,11 @@
-
+
-
+
@@ -439,11 +439,11 @@
-
+
-
+
@@ -490,11 +490,11 @@
-
+
-
+
@@ -541,11 +541,11 @@
-
+
-
+
@@ -592,11 +592,11 @@
-
+
-
+
@@ -643,11 +643,11 @@
-
+
-
+
@@ -694,11 +694,11 @@
-
+
-
+
@@ -745,11 +745,11 @@
-
+
-
+
@@ -796,11 +796,11 @@
-
+
-
+
@@ -847,11 +847,11 @@
-
+
-
+
@@ -898,11 +898,11 @@
-
+
-
+
@@ -949,11 +949,11 @@
-
+
-
+
@@ -1000,11 +1000,11 @@
-
+
-
+
@@ -1051,11 +1051,11 @@
-
+
-
+
@@ -1102,11 +1102,11 @@
-
+
-
+
@@ -1153,11 +1153,11 @@
-
+
-
+
@@ -1204,11 +1204,11 @@
-
+
-
+
@@ -1255,11 +1255,11 @@
-
+
-
+
@@ -1306,11 +1306,11 @@
-
+
-
+
@@ -1357,11 +1357,11 @@
-
+
-
+
@@ -1408,11 +1408,11 @@
-
+
-
+
@@ -1459,11 +1459,11 @@
-
+
-
+
@@ -1510,11 +1510,11 @@
-
+
-
+
@@ -1561,11 +1561,11 @@
-
+
-
+
@@ -1612,11 +1612,11 @@
-
+
-
+
@@ -1663,11 +1663,11 @@
-
+
-
+
@@ -1714,11 +1714,11 @@
-
+
-
+
@@ -1765,11 +1765,11 @@
-
+
-
+
@@ -1816,11 +1816,11 @@
-
+
-
+
@@ -1867,11 +1867,11 @@
-
+
-
+
@@ -1918,11 +1918,11 @@
-
+
-
+
diff --git a/lib/iris/tests/results/file_load/wind_levels.cml b/lib/iris/tests/results/file_load/wind_levels.cml
index b53327b191..15ebd44c9c 100644
--- a/lib/iris/tests/results/file_load/wind_levels.cml
+++ b/lib/iris/tests/results/file_load/wind_levels.cml
@@ -31,11 +31,11 @@
-
+
-
+
@@ -82,11 +82,11 @@
-
+
-
+
@@ -133,11 +133,11 @@
-
+
-
+
@@ -184,11 +184,11 @@
-
+
-
+
@@ -235,11 +235,11 @@
-
+
-
+
@@ -286,11 +286,11 @@
-
+
-
+
@@ -337,11 +337,11 @@
-
+
-
+
@@ -388,11 +388,11 @@
-
+
-
+
@@ -439,11 +439,11 @@
-
+
-
+
@@ -490,11 +490,11 @@
-
+
-
+
@@ -541,11 +541,11 @@
-
+
-
+
@@ -592,11 +592,11 @@
-
+
-
+
@@ -643,11 +643,11 @@
-
+
-
+
@@ -694,11 +694,11 @@
-
+
-
+
@@ -745,11 +745,11 @@
-
+
-
+
@@ -796,11 +796,11 @@
-
+
-
+
@@ -847,11 +847,11 @@
-
+
-
+
@@ -898,11 +898,11 @@
-
+
-
+
@@ -949,11 +949,11 @@
-
+
-
+
@@ -1000,11 +1000,11 @@
-
+
-
+
@@ -1051,11 +1051,11 @@
-
+
-
+
@@ -1102,11 +1102,11 @@
-
+
-
+
@@ -1153,11 +1153,11 @@
-
+
-
+
@@ -1204,11 +1204,11 @@
-
+
-
+
@@ -1255,11 +1255,11 @@
-
+
-
+
@@ -1306,11 +1306,11 @@
-
+
-
+
@@ -1357,11 +1357,11 @@
-
+
-
+
@@ -1408,11 +1408,11 @@
-
+
-
+
@@ -1459,11 +1459,11 @@
-
+
-
+
@@ -1510,11 +1510,11 @@
-
+
-
+
@@ -1561,11 +1561,11 @@
-
+
-
+
@@ -1612,11 +1612,11 @@
-
+
-
+
@@ -1663,11 +1663,11 @@
-
+
-
+
@@ -1714,11 +1714,11 @@
-
+
-
+
@@ -1765,11 +1765,11 @@
-
+
-
+
@@ -1816,11 +1816,11 @@
-
+
-
+
@@ -1867,11 +1867,11 @@
-
+
-
+
@@ -1918,11 +1918,11 @@
-
+
-
+
@@ -1969,11 +1969,11 @@
-
+
-
+
@@ -2020,11 +2020,11 @@
-
+
-
+
@@ -2071,11 +2071,11 @@
-
+
-
+
@@ -2122,11 +2122,11 @@
-
+
-
+
@@ -2173,11 +2173,11 @@
-
+
-
+
@@ -2224,11 +2224,11 @@
-
+
-
+
@@ -2275,11 +2275,11 @@
-
+
-
+
@@ -2326,11 +2326,11 @@
-
+
-
+
@@ -2377,11 +2377,11 @@
-
+
-
+
@@ -2428,11 +2428,11 @@
-
+
-
+
@@ -2479,11 +2479,11 @@
-
+
-
+
@@ -2530,11 +2530,11 @@
-
+
-
+
@@ -2581,11 +2581,11 @@
-
+
-
+
@@ -2632,11 +2632,11 @@
-
+
-
+
@@ -2683,11 +2683,11 @@
-
+
-
+
@@ -2734,11 +2734,11 @@
-
+
-
+
@@ -2785,11 +2785,11 @@
-
+
-
+
@@ -2836,11 +2836,11 @@
-
+
-
+
@@ -2887,11 +2887,11 @@
-
+
-
+
@@ -2938,11 +2938,11 @@
-
+
-
+
@@ -2989,11 +2989,11 @@
-
+
-
+
@@ -3040,11 +3040,11 @@
-
+
-
+
@@ -3091,11 +3091,11 @@
-
+
-
+
@@ -3142,11 +3142,11 @@
-
+
-
+
@@ -3193,11 +3193,11 @@
-
+
-
+
@@ -3244,11 +3244,11 @@
-
+
-
+
@@ -3295,11 +3295,11 @@
-
+
-
+
@@ -3346,11 +3346,11 @@
-
+
-
+
@@ -3397,11 +3397,11 @@
-
+
-
+
@@ -3448,11 +3448,11 @@
-
+
-
+
@@ -3499,11 +3499,11 @@
-
+
-
+
@@ -3550,11 +3550,11 @@
-
+
-
+
@@ -3601,11 +3601,11 @@
-
+
-
+
@@ -3652,11 +3652,11 @@
-
+
-
+
@@ -3703,11 +3703,11 @@
-
+
-
+
@@ -3754,11 +3754,11 @@
-
+
-
+
@@ -3805,11 +3805,11 @@
-
+
-
+
@@ -3856,11 +3856,11 @@
-
+
-
+
diff --git a/lib/iris/tests/results/merge/a_aux_b_aux.cml b/lib/iris/tests/results/merge/a_aux_b_aux.cml
new file mode 100644
index 0000000000..13c49ddfa3
--- /dev/null
+++ b/lib/iris/tests/results/merge/a_aux_b_aux.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/a_aux_b_dim.cml b/lib/iris/tests/results/merge/a_aux_b_dim.cml
new file mode 100644
index 0000000000..13c49ddfa3
--- /dev/null
+++ b/lib/iris/tests/results/merge/a_aux_b_dim.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/a_dim_b_aux.cml b/lib/iris/tests/results/merge/a_dim_b_aux.cml
new file mode 100644
index 0000000000..13c49ddfa3
--- /dev/null
+++ b/lib/iris/tests/results/merge/a_dim_b_aux.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/a_dim_b_dim.cml b/lib/iris/tests/results/merge/a_dim_b_dim.cml
new file mode 100644
index 0000000000..13c49ddfa3
--- /dev/null
+++ b/lib/iris/tests/results/merge/a_dim_b_dim.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/separable_combination.cml b/lib/iris/tests/results/merge/separable_combination.cml
new file mode 100644
index 0000000000..9ca61c352c
--- /dev/null
+++ b/lib/iris/tests/results/merge/separable_combination.cml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/string_a_b.cml b/lib/iris/tests/results/merge/string_a_b.cml
new file mode 100644
index 0000000000..f868af4d2d
--- /dev/null
+++ b/lib/iris/tests/results/merge/string_a_b.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/string_a_with_aux.cml b/lib/iris/tests/results/merge/string_a_with_aux.cml
new file mode 100644
index 0000000000..323b9dac80
--- /dev/null
+++ b/lib/iris/tests/results/merge/string_a_with_aux.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/string_a_with_dim.cml b/lib/iris/tests/results/merge/string_a_with_dim.cml
new file mode 100644
index 0000000000..323b9dac80
--- /dev/null
+++ b/lib/iris/tests/results/merge/string_a_with_dim.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/results/merge/string_b_with_dim.cml b/lib/iris/tests/results/merge/string_b_with_dim.cml
new file mode 100644
index 0000000000..111147663f
--- /dev/null
+++ b/lib/iris/tests/results/merge/string_b_with_dim.cml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/iris/tests/test_merge.py b/lib/iris/tests/test_merge.py
index ab0cc8b68a..bf392cd454 100644
--- a/lib/iris/tests/test_merge.py
+++ b/lib/iris/tests/test_merge.py
@@ -1,4 +1,4 @@
-# (C) British Crown Copyright 2010 - 2012, Met Office
+# (C) British Crown Copyright 2010 - 2013, Met Office
#
# This file is part of Iris.
#
@@ -27,7 +27,7 @@
import iris
import iris.cube
import iris.exceptions
-from iris.coords import DimCoord
+from iris.coords import DimCoord, AuxCoord
import iris.coords
import iris.tests.stock
@@ -179,6 +179,186 @@ def test_multi_split(self):
self.assertCML(cube, ('merge', 'multi_split.cml'))
+class TestCombination(tests.IrisTest):
+ def _make_cube(self, a, b, c, d, data=0):
+ cube_data = np.empty((4, 5), dtype=np.float32)
+ cube_data[:] = data
+ cube = iris.cube.Cube(cube_data)
+ cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32),
+ long_name='x', units='1'), 1)
+ cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32),
+ long_name='y', units='1'), 0)
+
+ for name, value in zip(['a', 'b', 'c', 'd'], [a, b, c, d]):
+ dtype = np.str if isinstance(value, basestring) else np.float32
+ cube.add_aux_coord(AuxCoord(np.array([value], dtype=dtype),
+ long_name=name, units='1'))
+
+ return cube
+
+ def test_separable_combination(self):
+ cubes = iris.cube.CubeList()
+ cubes.append(self._make_cube('2005', 'ECMWF',
+ 'HOPE-E, Sys 1, Met 1, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2005', 'ECMWF',
+ 'HOPE-E, Sys 1, Met 1, ENSEMBLES', 1))
+ cubes.append(self._make_cube('2005', 'ECMWF',
+ 'HOPE-E, Sys 1, Met 1, ENSEMBLES', 2))
+ cubes.append(self._make_cube('2026', 'UK Met Office',
+ 'HadGEM2, Sys 1, Met 1, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2026', 'UK Met Office',
+ 'HadGEM2, Sys 1, Met 1, ENSEMBLES', 1))
+ cubes.append(self._make_cube('2026', 'UK Met Office',
+ 'HadGEM2, Sys 1, Met 1, ENSEMBLES', 2))
+ cubes.append(self._make_cube('2002', 'CERFACS',
+ 'GELATO, Sys 0, Met 1, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2002', 'CERFACS',
+ 'GELATO, Sys 0, Met 1, ENSEMBLES', 1))
+ cubes.append(self._make_cube('2002', 'CERFACS',
+ 'GELATO, Sys 0, Met 1, ENSEMBLES', 2))
+ cubes.append(self._make_cube('2002', 'IFM-GEOMAR',
+ 'ECHAM5, Sys 1, Met 10, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2002', 'IFM-GEOMAR',
+ 'ECHAM5, Sys 1, Met 10, ENSEMBLES', 1))
+ cubes.append(self._make_cube('2002', 'IFM-GEOMAR',
+ 'ECHAM5, Sys 1, Met 10, ENSEMBLES', 2))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 10, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 11, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 12, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 13, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 14, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 15, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 16, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 17, ENSEMBLES', 0))
+ cubes.append(self._make_cube('2502', 'UK Met Office',
+ 'HadCM3, Sys 51, Met 18, ENSEMBLES', 0))
+ cube = cubes.merge()
+ self.assertCML(cube, ('merge', 'separable_combination.cml'),
+ checksum=False)
+
+
+class TestDimSelection(tests.IrisTest):
+ def _make_cube(self, a, b, data=0, a_dim=False, b_dim=False):
+ cube_data = np.empty((4, 5), dtype=np.float32)
+ cube_data[:] = data
+ cube = iris.cube.Cube(cube_data)
+ cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32),
+ long_name='x', units='1'), 1)
+ cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32),
+ long_name='y', units='1'), 0)
+
+ for name, value, dim in zip(['a', 'b'], [a, b], [a_dim, b_dim]):
+ dtype = np.str if isinstance(value, basestring) else np.float32
+ ctype = DimCoord if dim else AuxCoord
+ coord = ctype(np.array([value], dtype=dtype),
+ long_name=name, units='1')
+ cube.add_aux_coord(coord)
+
+ return cube
+
+ def test_string_a_with_aux(self):
+ templates = (('a', 0), ('b', 1), ('c', 2), ('d', 3))
+ cubes = [self._make_cube(a, b) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'string_a_with_aux.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), AuxCoord))
+ self.assertTrue(isinstance(cube.coord('b'), DimCoord))
+ self.assertTrue(cube.coord('b') in cube.dim_coords)
+
+ def test_string_b_with_aux(self):
+ templates = ((0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'))
+ cubes = [self._make_cube(a, b) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'string_b_with_aux.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), DimCoord))
+ self.assertTrue(cube.coord('a') in cube.dim_coords)
+ self.assertTrue(isinstance(cube.coord('b'), AuxCoord))
+
+ def test_string_a_with_dim(self):
+ templates = (('a', 0), ('b', 1), ('c', 2), ('d', 3))
+ cubes = [self._make_cube(a, b, b_dim=True) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'string_a_with_dim.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), AuxCoord))
+ self.assertTrue(isinstance(cube.coord('b'), DimCoord))
+ self.assertTrue(cube.coord('b') in cube.dim_coords)
+
+ def test_string_b_with_aux(self):
+ templates = ((0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'))
+ cubes = [self._make_cube(a, b, a_dim=True) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'string_b_with_dim.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), DimCoord))
+ self.assertTrue(cube.coord('a') in cube.dim_coords)
+ self.assertTrue(isinstance(cube.coord('b'), AuxCoord))
+
+ def test_string_a_b(self):
+ templates = (('a', '0'), ('b', '1'), ('c', '2'), ('d', '3'))
+ cubes = [self._make_cube(a, b) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'string_a_b.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), AuxCoord))
+ self.assertTrue(isinstance(cube.coord('b'), AuxCoord))
+
+ def test_a_aux_b_aux(self):
+ templates = ((0, 10), (1, 11), (2, 12), (3, 13))
+ cubes = [self._make_cube(a, b) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'a_aux_b_aux.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), DimCoord))
+ self.assertTrue(cube.coord('a') in cube.dim_coords)
+ self.assertTrue(isinstance(cube.coord('b'), DimCoord))
+ self.assertTrue(cube.coord('b') in cube.aux_coords)
+
+ def test_a_aux_b_dim(self):
+ templates = ((0, 10), (1, 11), (2, 12), (3, 13))
+ cubes = [self._make_cube(a, b, b_dim=True) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'a_aux_b_dim.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), DimCoord))
+ self.assertTrue(cube.coord('a') in cube.aux_coords)
+ self.assertTrue(isinstance(cube.coord('b'), DimCoord))
+ self.assertTrue(cube.coord('b') in cube.dim_coords)
+
+ def test_a_dim_b_aux(self):
+ templates = ((0, 10), (1, 11), (2, 12), (3, 13))
+ cubes = [self._make_cube(a, b, a_dim=True) for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'a_dim_b_aux.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), DimCoord))
+ self.assertTrue(cube.coord('a') in cube.dim_coords)
+ self.assertTrue(isinstance(cube.coord('b'), DimCoord))
+ self.assertTrue(cube.coord('b') in cube.aux_coords)
+
+ def test_a_dim_b_dim(self):
+ templates = ((0, 10), (1, 11), (2, 12), (3, 13))
+ cubes = [self._make_cube(a, b, a_dim=True, b_dim=True) \
+ for a, b in templates]
+ cube = iris.cube.CubeList(cubes).merge()[0]
+ self.assertCML(cube, ('merge', 'a_dim_b_dim.cml'),
+ checksum=False)
+ self.assertTrue(isinstance(cube.coord('a'), DimCoord))
+ self.assertTrue(cube.coord('a') in cube.dim_coords)
+ self.assertTrue(isinstance(cube.coord('b'), DimCoord))
+ self.assertTrue(cube.coord('b') in cube.aux_coords)
+
+
class TestTimeTripleMerging(tests.IrisTest):
def _make_cube(self, a, b, c, data=0):
cube_data = np.empty((4, 5), dtype=np.float32)