🐛 Bug Report
Loading some NetCDF files fail to merge into a single cube, but promoting the relevant scalar coordinates and concatenating does collapse into a single cube.
How To Reproduce
I have some NetCDF files which I would expect to merge into a single cube when loaded, but the cubes fail to merge. For example
>>> from pathlib import Path
>>> import iris
>>> p = Path("/path/to/files/")
>>> files = list(p.glob("*nc"))
>>> def callback(cube, field, filename):
... del cube.attributes["history"]
>>> name_con = iris.Constraint(cube_func=lambda cube: cube.name().startswith("air_temperature"))
>>> coord_con = iris.Constraint(cube_func=lambda cube: any(coord.name() == "pressure"
... for coord in cube.dim_coords))
>>> cubes = iris.load(files, name_con & coord_con, callback=callback)
>>> print(cubes)
0: air_temperature / (K) (time: 2; pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
1: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
If I load the cubes individually and then attempt to manually merge them I get a MergeError as you might expect:
>>> # now load raw and attempt to coerce them into a single cube
>>> cubes = iris.load_raw(files, name_con & coord_con, callback=callback)
>>> print(cubes)
0: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
1: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
2: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
>>> # attempt to merge into a single cube
>>> print(cubes.merge_cube())
Traceback (most recent call last):
...
File ".../lib/python3.12/site-packages/iris/cube.py", line 348, in merge_cube
proto_cube.register(c, error_on_mismatch=True)
File ".../lib/python3.12/site-packages/iris/_merge.py", line 1301, in register
match = coord_payload.match_signature(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.12/site-packages/iris/_merge.py", line 271, in match_signature
raise iris.exceptions.MergeError(msgs)
iris.exceptions.MergeError: failed to merge into a single cube.
Coordinates in cube.aux_coords (non-scalar) differ: air_temperature status_flag.
Metadata wise the coordinates look compatible
>>> # examine the status_flag coordinate
>>> for cube in cubes:
... print(cube.coord("air_temperature status_flag"))
AuxCoord : air_temperature status_flag / (no_unit)
points: <lazy>
shape: (33, 970, 1042)
dtype: int8
standard_name: 'air_temperature status_flag'
var_name: 'flag'
attributes:
flag_meanings 'above_surface_pressure below_surface_pressure'
flag_values [0 1]
AuxCoord : air_temperature status_flag / (no_unit)
points: <lazy>
shape: (33, 970, 1042)
dtype: int8
standard_name: 'air_temperature status_flag'
var_name: 'flag'
attributes:
flag_meanings 'above_surface_pressure below_surface_pressure'
flag_values [0 1]
AuxCoord : air_temperature status_flag / (no_unit)
points: <lazy>
shape: (33, 970, 1042)
dtype: int8
standard_name: 'air_temperature status_flag'
var_name: 'flag'
attributes:
flag_meanings 'above_surface_pressure below_surface_pressure'
flag_values [0 1]
If I promote the relevant scalar coordinate to a singleton dimension (along with other coordinates spanning that dimension) I can then successfully concatenate into a single cube
>>> # attempt to concatenate the cubes by promoting the scalar dimension to a
>>> # singleton dimension
>>> cubes = iris.cube.CubeList(iris.util.new_axis(cube, "time",
... expand_extras=(cube.coord("forecast_period"),
... cube.coord("air_temperature status_flag")))
... for cube in cubes)
>>> print(cubes.concatenate_cube())
air_temperature / (K) (time: 3; pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
Dimension coordinates:
time x - - -
pressure - x - -
projection_y_coordinate - - x -
projection_x_coordinate - - - x
Auxiliary coordinates:
forecast_period x - - -
air_temperature status_flag x x x x
Scalar coordinates:
forecast_reference_time 2025-10-01 00:00:00
Attributes:
Conventions 'CF-1.7, UKMO-1.0'
institution 'Met Office'
least_significant_digit np.int64(1)
mosg__forecast_run_duration 'PT54H'
mosg__grid_domain 'uk_extended'
mosg__grid_type 'standard'
mosg__grid_version '1.7.0'
mosg__model_configuration 'uk_det'
source 'Met Office Unified Model'
title 'UKV Model Forecast on UK 2 km Standard Grid'
um_version '13.1'
which is what I would expect to happen. It is unclear to me why the status_flag coordinate should prevent a merge but not prevent concatenation?
Expected behaviour
On load there would be a single cube with a time dimension of length 3.
Environment
- OS & Version: RHEL7
- Iris Version: 3.13.1
Additional context
I get the same result with all of the COMBINE_POLICY options:
# try the different load policies
>>> for policy in ("legacy", "recommended", "default", "comprehensive"):
... iris.COMBINE_POLICY.set(policy)
... cubes = iris.load(files, name_con & coord_con, callback=callback)
... print(policy)
... print(cubes)
legacy
0: air_temperature / (K) (time: 2; pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
1: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
recommended
0: air_temperature / (K) (time: 2; pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
1: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
default
0: air_temperature / (K) (time: 2; pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
1: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
comprehensive
0: air_temperature / (K) (time: 2; pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
1: air_temperature / (K) (pressure: 33; projection_y_coordinate: 970; projection_x_coordinate: 1042)
🐛 Bug Report
Loading some NetCDF files fail to merge into a single cube, but promoting the relevant scalar coordinates and concatenating does collapse into a single cube.
How To Reproduce
I have some NetCDF files which I would expect to merge into a single cube when loaded, but the cubes fail to merge. For example
If I load the cubes individually and then attempt to manually merge them I get a MergeError as you might expect:
Metadata wise the coordinates look compatible
If I promote the relevant scalar coordinate to a singleton dimension (along with other coordinates spanning that dimension) I can then successfully concatenate into a single cube
which is what I would expect to happen. It is unclear to me why the status_flag coordinate should prevent a merge but not prevent concatenation?
Expected behaviour
On load there would be a single cube with a time dimension of length 3.
Environment
Additional context
I get the same result with all of the COMBINE_POLICY options: