Exercise 4

The following exercise is designed to give you experience of identifying why two cubes are not merging. Work is underway to make this identification process more automatic, but the resolution of the identified differences will still be a necessary process.

There are 6 problems, each of which are not merging into a single cube as desired. In no particular order the problems are:

  1. one of the cubes has a history attribute, but the other doesn't
  2. one of the cubes has bounds on the spatial coordinates, but the other doesn't
  3. the two cubes have different time coordinate units
  4. the two cubes have different data dtypes
  5. the two cubes have different long names
  6. the two cubes have different shapes (the data must currently be loaded to correct this)

The files can be found in the repository along with this course in exercises/iris/merge/. There are two files to be loaded for each exercise: merge_exercise.{problem_number}.f1.nc and merge_exercise.{problem_number}.f2.nc.

Identify, and correct, the reason that the two cubes are not merging for all 6 sets of files.

Problem 1


In [1]:
import iris

In [2]:
cube1 = iris.load_cube('../resources/merge_exercise.1.f1.nc')
cube2 = iris.load_cube('../resources/merge_exercise.1.f2.nc')
merged = iris.cube.CubeList([cube1, cube2]).merge_cube()


/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
---------------------------------------------------------------------------
MergeError                                Traceback (most recent call last)
<ipython-input-2-e34cd90522d0> in <module>()
      1 cube1 = iris.load_cube('../resources/merge_exercise.1.f1.nc')
      2 cube2 = iris.load_cube('../resources/merge_exercise.1.f2.nc')
----> 3 merged = iris.cube.CubeList([cube1, cube2]).merge_cube()

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/cube.py in merge_cube(self)
    376         proto_cube = iris._merge.ProtoCube(self[0])
    377         for cube in self[1:]:
--> 378             proto_cube.register(cube, error_on_mismatch=True)
    379 
    380         # Extract the merged cube from the ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in register(self, cube, error_on_mismatch)
   1252         """
   1253         match = self._cube_signature.match(self._build_signature(cube),
-> 1254                                            error_on_mismatch)
   1255         if match:
   1256             coord_payload = self._extract_coord_payload(cube)

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in match(self, other, error_on_mismatch)
    408         match = not bool(msgs)
    409         if error_on_mismatch and not match:
--> 410             raise iris.exceptions.MergeError(msgs)
    411         return match
    412 

MergeError: failed to merge into a single cube.
  cube.attributes keys differ: 'History'

In [3]:
cube1 = iris.load_cube('../resources/merge_exercise.2.f1.nc')
cube2 = iris.load_cube('../resources/merge_exercise.2.f2.nc')
merged = iris.cube.CubeList([cube1, cube2]).merge_cube()


/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
---------------------------------------------------------------------------
MergeError                                Traceback (most recent call last)
<ipython-input-3-9f1b11b3079e> in <module>()
      1 cube1 = iris.load_cube('../resources/merge_exercise.2.f1.nc')
      2 cube2 = iris.load_cube('../resources/merge_exercise.2.f2.nc')
----> 3 merged = iris.cube.CubeList([cube1, cube2]).merge_cube()

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/cube.py in merge_cube(self)
    376         proto_cube = iris._merge.ProtoCube(self[0])
    377         for cube in self[1:]:
--> 378             proto_cube.register(cube, error_on_mismatch=True)
    379 
    380         # Extract the merged cube from the ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in register(self, cube, error_on_mismatch)
   1252         """
   1253         match = self._cube_signature.match(self._build_signature(cube),
-> 1254                                            error_on_mismatch)
   1255         if match:
   1256             coord_payload = self._extract_coord_payload(cube)

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in match(self, other, error_on_mismatch)
    408         match = not bool(msgs)
    409         if error_on_mismatch and not match:
--> 410             raise iris.exceptions.MergeError(msgs)
    411         return match
    412 

MergeError: failed to merge into a single cube.
  cube.long_name differs: 'The first timestep' != 'The second timestep'

In [4]:
cube1 = iris.load_cube('../resources/merge_exercise.3.f1.nc')
cube2 = iris.load_cube('../resources/merge_exercise.3.f2.nc')
print(cube1.coord('time'))
print(cube2.coord('time'))
merged = iris.cube.CubeList([cube1, cube2]).merge_cube()


DimCoord([2009-09-09 17:10:00], standard_name='time', calendar='gregorian', var_name='time')
DimCoord([2009-09-09 17:20:00], standard_name='time', calendar='gregorian', var_name='time')
/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
---------------------------------------------------------------------------
MergeError                                Traceback (most recent call last)
<ipython-input-4-2e2148ac008e> in <module>()
      3 print(cube1.coord('time'))
      4 print(cube2.coord('time'))
----> 5 merged = iris.cube.CubeList([cube1, cube2]).merge_cube()

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/cube.py in merge_cube(self)
    376         proto_cube = iris._merge.ProtoCube(self[0])
    377         for cube in self[1:]:
--> 378             proto_cube.register(cube, error_on_mismatch=True)
    379 
    380         # Extract the merged cube from the ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in register(self, cube, error_on_mismatch)
   1256             coord_payload = self._extract_coord_payload(cube)
   1257             match = coord_payload.match_signature(self._coord_signature,
-> 1258                                                   error_on_mismatch)
   1259         if match:
   1260             # Register the cube as a source-cube for this ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in match_signature(self, signature, error_on_mismatch)
    274         match = not bool(msgs)
    275         if error_on_mismatch and not match:
--> 276             raise iris.exceptions.MergeError(msgs)
    277         return match
    278 

MergeError: failed to merge into a single cube.
  Coordinates in cube.aux_coords (scalar) differ: time.

In [5]:
cube1 = iris.load_cube('../resources/merge_exercise.4.f1.nc')
cube2 = iris.load_cube('../resources/merge_exercise.4.f2.nc')
merged = iris.cube.CubeList([cube1, cube2]).merge_cube()


/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
---------------------------------------------------------------------------
MergeError                                Traceback (most recent call last)
<ipython-input-5-a56bc926bfb5> in <module>()
      1 cube1 = iris.load_cube('../resources/merge_exercise.4.f1.nc')
      2 cube2 = iris.load_cube('../resources/merge_exercise.4.f2.nc')
----> 3 merged = iris.cube.CubeList([cube1, cube2]).merge_cube()

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/cube.py in merge_cube(self)
    376         proto_cube = iris._merge.ProtoCube(self[0])
    377         for cube in self[1:]:
--> 378             proto_cube.register(cube, error_on_mismatch=True)
    379 
    380         # Extract the merged cube from the ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in register(self, cube, error_on_mismatch)
   1252         """
   1253         match = self._cube_signature.match(self._build_signature(cube),
-> 1254                                            error_on_mismatch)
   1255         if match:
   1256             coord_payload = self._extract_coord_payload(cube)

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in match(self, other, error_on_mismatch)
    408         match = not bool(msgs)
    409         if error_on_mismatch and not match:
--> 410             raise iris.exceptions.MergeError(msgs)
    411         return match
    412 

MergeError: failed to merge into a single cube.
  cube data dtype differs: float32 != float64

In [6]:
cube1 = iris.load_cube('../resources/merge_exercise.5.f1.nc')
cube2 = iris.load_cube('../resources/merge_exercise.5.f2.nc')
merged = iris.cube.CubeList([cube1, cube2]).merge_cube()


/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
---------------------------------------------------------------------------
MergeError                                Traceback (most recent call last)
<ipython-input-6-5ad8d5bd6348> in <module>()
      1 cube1 = iris.load_cube('../resources/merge_exercise.5.f1.nc')
      2 cube2 = iris.load_cube('../resources/merge_exercise.5.f2.nc')
----> 3 merged = iris.cube.CubeList([cube1, cube2]).merge_cube()

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/cube.py in merge_cube(self)
    376         proto_cube = iris._merge.ProtoCube(self[0])
    377         for cube in self[1:]:
--> 378             proto_cube.register(cube, error_on_mismatch=True)
    379 
    380         # Extract the merged cube from the ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in register(self, cube, error_on_mismatch)
   1252         """
   1253         match = self._cube_signature.match(self._build_signature(cube),
-> 1254                                            error_on_mismatch)
   1255         if match:
   1256             coord_payload = self._extract_coord_payload(cube)

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in match(self, other, error_on_mismatch)
    408         match = not bool(msgs)
    409         if error_on_mismatch and not match:
--> 410             raise iris.exceptions.MergeError(msgs)
    411         return match
    412 

MergeError: failed to merge into a single cube.
  cube.shape differs: (100, 100) != (1, 100, 100)

In [7]:
cube1 = iris.load_cube('../resources/merge_exercise.6.f1.nc')
cube2 = iris.load_cube('../resources/merge_exercise.6.f2.nc')
merged = iris.cube.CubeList([cube1, cube2]).merge_cube()


/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/fileformats/cf.py:1140: IrisDeprecation: NetCDF default loading behaviour currently does not expose variables which define reference surfaces for dimensionless vertical coordinates as independent Cubes. This behaviour is deprecated in favour of automatic promotion to Cubes. To switch to the new behaviour, set iris.FUTURE.netcdf_promote to True.
  warn_deprecated(msg)
---------------------------------------------------------------------------
MergeError                                Traceback (most recent call last)
<ipython-input-7-078b7bd81895> in <module>()
      1 cube1 = iris.load_cube('../resources/merge_exercise.6.f1.nc')
      2 cube2 = iris.load_cube('../resources/merge_exercise.6.f2.nc')
----> 3 merged = iris.cube.CubeList([cube1, cube2]).merge_cube()

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/cube.py in merge_cube(self)
    376         proto_cube = iris._merge.ProtoCube(self[0])
    377         for cube in self[1:]:
--> 378             proto_cube.register(cube, error_on_mismatch=True)
    379 
    380         # Extract the merged cube from the ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in register(self, cube, error_on_mismatch)
   1256             coord_payload = self._extract_coord_payload(cube)
   1257             match = coord_payload.match_signature(self._coord_signature,
-> 1258                                                   error_on_mismatch)
   1259         if match:
   1260             # Register the cube as a source-cube for this ProtoCube.

/Users/dawson/miniconda3/envs/python_workshop/lib/python3.5/site-packages/iris/_merge.py in match_signature(self, signature, error_on_mismatch)
    274         match = not bool(msgs)
    275         if error_on_mismatch and not match:
--> 276             raise iris.exceptions.MergeError(msgs)
    277         return match
    278 

MergeError: failed to merge into a single cube.
  Coordinates in cube.dim_coords differ: grid_latitude, grid_longitude.