Skip to content

Time coordinate with length 0 cannot be printed #6531

Open
@schlunma

Description

@schlunma

🐛 Bug Report

A time coordinate with length 0 causes a ValueError when printed.

How To Reproduce

Steps to reproduce the behaviour:

from iris.coords import DimCoord

t_coord = DimCoord([], standard_name="time", units="days since 1999-01-01")
print(t_coord)

gives

ValueError: cannot call `vectorize` on size 0 inputs unless `otypes` is set
Full traceback
Traceback (most recent call last):
  File "/home/manuel/scripts/iris/dim_0.py", line 11, in <module>
    print(t_coord)
    ~~~~~^^^^^^^^^
  File "/home/manuel/iris/lib/iris/coords.py", line 573, in __str__
    return self.summary()
           ~~~~~~~~~~~~^^
  File "/home/manuel/iris/lib/iris/coords.py", line 391, in summary
    data_str = array_summary(
        self._values,
    ...<3 lines>...
        precision=precision,
    )
  File "/home/manuel/iris/lib/iris/coords.py", line 329, in array_summary
    data = np.array(self.units.num2date(data))
                    ~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/manuel/iris/lib/iris/common/mixin.py", line 207, in num2date
    result = vfunc(result)
  File "/home/manuel/micromamba/envs/esm/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py", line 2522, in __call__
    return self._call_as_normal(*args, **kwargs)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/manuel/micromamba/envs/esm/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py", line 2515, in _call_as_normal
    return self._vectorize_call(func=func, args=vargs)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/manuel/micromamba/envs/esm/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py", line 2600, in _vectorize_call
    ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/home/manuel/micromamba/envs/esm/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py", line 2556, in _get_ufunc_and_otypes
    raise ValueError('cannot call `vectorize` on size 0 inputs '
                     'unless `otypes` is set')
ValueError: cannot call `vectorize` on size 0 inputs unless `otypes` is set

Within ESMValTool, we also found a different, but related error (I wasn't able to produce a MWE for this): ValueError: max() iterable argument is empty

Full traceback
File "/home/manuel/ESMValCore/esmvalcore/preprocessor/_multimodel.py", line 202, in _map_to_new_time
    print(new_cube.coord("time"))
    ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/manuel/iris/lib/iris/coords.py", line 573, in __str__
    return self.summary()
           ~~~~~~~~~~~~^^
  File "/home/manuel/iris/lib/iris/coords.py", line 391, in summary
    data_str = array_summary(
        self._values,
    ...<3 lines>...
        precision=precision,
    )
  File "/home/manuel/iris/lib/iris/coords.py", line 350, in array_summary
    length = max(len(str(x)) for x in data.flatten())
ValueError: max() iterable argument is empty

Expected behaviour

Since I assume that coordinates of size 0 are a feature and not a bug (see additional context below), no error should be raised.

Environment

  • OS & Version: Linux
  • Iris Version: Current main branch

Additional context

I assume that dimensions of size 0 are a feature, not a bug. Here are my clues:

  • Numpy allows this: np.ones((0, 12, 24)) is perfectly fine
  • The CF conventions seem to allow this: Dimensions may be of any size, including unity.
  • Setting up, saving, and loading a cube with a (non-temporal) dimension of size 0 is very simple with Iris and works perfectly fine.
from pathlib import Path
import iris
from iris.cube import Cube
from iris.coords import DimCoord

y_coord = DimCoord([], var_name="y")
cube = Cube([], dim_coords_and_dims=[(y_coord, 0)])
print(y_coord)
print(cube)

path = Path.home() / "test.nc"
iris.save(cube, path)

gives

DimCoord :  y / (unknown)
    points: []
    shape: (0,)
    dtype: float64
    var_name: 'y'
unknown / (unknown)                 (y: 0)
    Dimension coordinates:
        y                             x

Here is the saved data:

netcdf test {
dimensions:
        y = UNLIMITED ; // (0 currently)
variables:
        double unknown(y) ;
        double y(y) ;

// global attributes:
                :Conventions = "CF-1.7" ;
data:
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions