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

Cannot load cubes that contain multiple variables with array-type attributes with different sizes #6027

Closed
schlunma opened this issue Jun 26, 2024 · 1 comment · Fixed by #6181
Assignees
Milestone

Comments

@schlunma
Copy link
Contributor

🐛 Bug Report

How To Reproduce

Steps to reproduce the behaviour:

import iris
from iris.cube import Cube, CubeList
print("iris version", iris.__version__)

iris.FUTURE.save_split_attrs = True  # commenting this does not change the outcome

cubes = CubeList([
    Cube(0.0, var_name='a', attributes={'att': [0, 1]}),
    Cube(0.0, var_name='b', attributes={'att': [0, 1, 2]}),
])

path = 'data/cubes_with_attributes_bug.nc'
iris.save(cubes, path)
print("Saved", path)

loaded_cubes = iris.load(path)

gives

iris version 3.9.0
Saved data/cubes_with_attributes_bug.nc
Traceback (most recent call last):
  File "/home/b/b309141/scripts/iris/attributes.py", line 20, in <module>
    loaded_cubes = iris.load(path)
                   ^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/__init__.py", line 326, in load
    return _load_collection(uris, constraints, callback).merged().cubes()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/cube.py", line 126, in merged
    return _CubeFilterCollection([pair.merged(unique) for pair in self.pairs])
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/cube.py", line 126, in <listcomp>
    return _CubeFilterCollection([pair.merged(unique) for pair in self.pairs])
                                  ^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/cube.py", line 85, in merged
    return _CubeFilter(self.constraint, self.cubes.merge(unique))
                                        ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/cube.py", line 482, in merge
    if target_proto_cube.register(cube):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/_merge.py", line 1310, in register
    match = cube_signature.match(other, error_on_mismatch)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/_merge.py", line 427, in match
    msgs = self._defn_msgs(other.defn)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/_merge.py", line 372, in _defn_msgs
    if self_defn.attributes != other_defn.attributes:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/cube.py", line 910, in __eq__
    result = self.locals == other.locals and self.globals == other.globals
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/work/bd0854/b309141/miniforge3/envs/esm/lib/python3.11/site-packages/iris/common/mixin.py", line 104, in __eq__
    match = value == other[key]
            ^^^^^^^^^^^^^^^^^^^
ValueError: operands could not be broadcast together with shapes (2,) (3,)

It looks like this is related to the new local/global attribute change introduced in iris 3.8.0. Replacing the simple == with a np.array_equal in two places of the code fixes this (this should also works with other types, not only with numpy arrays).

Expected behaviour

No error when loading the data.

Environment

  • OS & Version: Red Hat Enterprise Linux 8.8 (Ootpa)
  • Iris Version: 3.9.0
@ukmo-ccbunney
Copy link
Contributor

Thanks for the bug report @schlunma

It looks like this attribute comparison was relying on some old behaviour of numpy where comparing arrays of different size would return a scalar False. Doing this now throws an error, as you've found.

You proposed solution looks sensible and probably means we can clean up a bit of the other logic in the equality operator too.

I'll raise PR with a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

5 participants