Skip to content

Preprocessor multimodel_statistics fails when data have no horizontal dimension #891

@stefsmeets

Description

@stefsmeets

Describe the bug
Hi all, I'm developing some tests for the multimodel statistics using real data (#856), and I'm coming accross this bug:

Running multimodel statistics with a list of cubes with no horizontal dimension, will result in
iris.exceptions.CoordinateNotFoundError: 'Expected to find exactly 1 depth coordinate, but found none.'

The bug can be reproduced by:

cubes = [cube[:, :, 0, 0] for cube in cubes]
multi_model_statistics(cubes, span='full', statistics=['mean'])
See the full stack trace below.
timeseries_cubes_month = [<iris 'Cube' of air_temperature / (K) (time: 14; air_pressure: 2; latitude: 3; longitude: 2)>, <iris 'Cube' of air_te... 3; longitude: 2)>, <iris 'Cube' of air_temperature / (K) (time: 14; air_pressure: 2; latitude: 3; longitude: 2)>, ...]

    @pytest.mark.functional
    # @pytest.mark.xfail('iris.exceptions.CoordinateNotFoundError')
    def test_multimodel_no_horizontal_dimension(timeseries_cubes_month):
        """Test statistic without horizontal dimension using monthly data."""
        span = 'full'
        cubes = timeseries_cubes_month
        cubes = [cube[:, :, 0, 0] for cube in cubes]
        # Coordinate not found error
        # iris.exceptions.CoordinateNotFoundError:
        # 'Expected to find exactly 1 depth coordinate, but found none.'
>       multimodel_test(cubes, span=span, statistic='mean')

tests/functional/test_multimodel.py:207:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/functional/test_multimodel.py:125: in multimodel_test
    output = multi_model_statistics(cubes, span=span, statistics=statistics)
esmvalcore/preprocessor/_multimodel.py:439: in multi_model_statistics
    statistic_cube = _assemble_full_data(cubes, statistic)
esmvalcore/preprocessor/_multimodel.py:355: in _assemble_full_data
    stats_cube = _put_in_cube(cubes[0], stats_dats, statistic, time_axis)
esmvalcore/preprocessor/_multimodel.py:180: in _put_in_cube
    plev = template_cube.coord('depth')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <iris 'Cube' of air_temperature / (K) (time: 14; air_pressure: 2)>, name_or_coord = 'depth', standard_name = None, long_name = None
var_name = None, attributes = None, axis = None, contains_dimension = None, dimensions = None, coord_system = None, dim_coords = None

    def coord(self, name_or_coord=None, standard_name=None,
              long_name=None, var_name=None, attributes=None, axis=None,
              contains_dimension=None, dimensions=None, coord_system=None,
              dim_coords=None):
        """
        Return a single coord given the same arguments as :meth:`Cube.coords`.

        .. note::

            If the arguments given do not result in precisely 1 coordinate
            being matched, an :class:`iris.exceptions.CoordinateNotFoundError`
            is raised.

        .. seealso::

            :meth:`Cube.coords()<iris.cube.Cube.coords>` for full keyword
            documentation.

        """
        coords = self.coords(name_or_coord=name_or_coord,
                             standard_name=standard_name,
                             long_name=long_name, var_name=var_name,
                             attributes=attributes, axis=axis,
                             contains_dimension=contains_dimension,
                             dimensions=dimensions,
                             coord_system=coord_system,
                             dim_coords=dim_coords)

        if len(coords) > 1:
            msg = 'Expected to find exactly 1 coordinate, but found %s. ' \
                  'They were: %s.' % (len(coords), ', '.join(coord.name() for
                                                             coord in coords))
            raise iris.exceptions.CoordinateNotFoundError(msg)
        elif len(coords) == 0:
            _name = name_or_coord
            if name_or_coord is not None:
                if not isinstance(name_or_coord, six.string_types):
                    _name = name_or_coord.name()
            bad_name = _name or standard_name or long_name or ''
            msg = 'Expected to find exactly 1 %s coordinate, but found ' \
                  'none.' % bad_name
>           raise iris.exceptions.CoordinateNotFoundError(msg)
E           iris.exceptions.CoordinateNotFoundError: 'Expected to find exactly 1 depth coordinate, but found none.'

../../miniconda3/envs/esmvaltool/lib/python3.8/site-packages/iris/cube.py:1497: CoordinateNotFoundError

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpreprocessorRelated to the preprocessor

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions