Skip to content

Commit e91f6b2

Browse files
committed
Implement combine_cube as util, and redirect test.
1 parent 046d09f commit e91f6b2

File tree

2 files changed

+82
-10
lines changed

2 files changed

+82
-10
lines changed

lib/iris/tests/unit/test_combine_cubes.py renamed to lib/iris/tests/unit/util/test_combine_cubes.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import pytest
1414

1515
from iris import LoadPolicy
16-
from iris._combine import _combine_cubes
1716
from iris.tests.unit.fileformats.test_load_functions import cu
17+
from iris.util import combine_cubes
1818

1919

2020
@pytest.fixture(params=list(LoadPolicy.SETTINGS.keys()))
@@ -23,14 +23,6 @@ def options(request):
2323
return request.param # Return the name of the attribute to test.
2424

2525

26-
# Interface to convert settings-name / kwargs into an options dict,
27-
# TODO: remove this wrapper when the API of "combine_cubes" is opened up.
28-
def combine_cubes(cubes, settings_name="default", **kwargs):
29-
options = LoadPolicy.SETTINGS[settings_name]
30-
options.update(kwargs)
31-
return _combine_cubes(cubes, options)
32-
33-
3426
class Test:
3527
def test_mergeable(self, options):
3628
c1, c2 = cu(t=1), cu(t=2)

lib/iris/util.py

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import os.path
1616
import sys
1717
import tempfile
18-
from typing import Literal
18+
from typing import TYPE_CHECKING, List, Literal
1919
from warnings import warn
2020

2121
import cf_units
@@ -31,6 +31,9 @@
3131
import iris.exceptions
3232
import iris.warnings
3333

34+
if TYPE_CHECKING:
35+
from iris.cube import Cube, CubeList
36+
3437

3538
def broadcast_to_shape(array, shape, dim_map, chunks=None):
3639
"""Broadcast an array to a given shape.
@@ -2343,3 +2346,80 @@ def _print_xml(doc):
23432346
"""
23442347
result = doc.toprettyxml(indent=" ")
23452348
return result.replace("
", "\n")
2349+
2350+
2351+
def combine_cubes(
2352+
cubes: List[Cube],
2353+
options: str | dict | None = None,
2354+
**kwargs,
2355+
) -> CubeList:
2356+
"""Combine cubes, according to "combine options".
2357+
2358+
Applies a combination of :meth:`~iris.util.equalise_cubes`,
2359+
:meth:`~iris.cube.CubeList.merge` and/or :meth:`~iris.cube.CubeList.concatenate`
2360+
steps to the given cubes, as determined by the given settings (from `options` and
2361+
`kwargs`).
2362+
2363+
Parameters
2364+
----------
2365+
cubes : list of :class:`~iris.cube.Cube`
2366+
A list of cubes to combine.
2367+
2368+
options : str or dict, optional
2369+
Either a standard "combine settings" name, i.e. one of the
2370+
:data:`iris.CombineOptions.SETTINGS_NAMES`, or a dictionary of
2371+
settings options, as described for :class:`~iris.CombineOptions`.
2372+
Defaults to the current value of :data:`iris.LOAD_POLICY.settings`.
2373+
2374+
kwargs : dict
2375+
Individual option setting values, i.e. values for keys named in
2376+
:data:`iris.CombineOptions.OPTION_KEYS`, as described for
2377+
:meth:`~iris.CombineOptions.set`. These take precedence over those set by the
2378+
`options` arg.
2379+
2380+
Returns
2381+
-------
2382+
:class:`~iris.cube.CubeList`
2383+
2384+
.. Note::
2385+
A ``support_multiple_references`` keyword/property is treated as a valid
2386+
option, but it has *no* effect on :func:`combine_cubes` because this option
2387+
only acts during load operations.
2388+
2389+
Examples
2390+
--------
2391+
>>> results = combine_cubes(cubes)
2392+
>>> results = combine_cubes(cubes, options=CombineOptions("recommended"))
2393+
>>> results = combine_cubes(cubes, repeat_until_unchanged=True)
2394+
2395+
"""
2396+
# TODO: somehow, provide a real + useful working code example
2397+
2398+
from iris import LOAD_POLICY, CombineOptions
2399+
from iris._combine import _combine_cubes
2400+
2401+
if options is None:
2402+
opts_dict = LOAD_POLICY.settings()
2403+
elif isinstance(options, str):
2404+
if options in CombineOptions.SETTINGS:
2405+
opts_dict = CombineOptions.SETTINGS[options]
2406+
else:
2407+
msg = (
2408+
"Unrecognised settings name : expected one of "
2409+
f"{tuple(CombineOptions.SETTINGS)}."
2410+
)
2411+
raise ValueError(msg)
2412+
elif isinstance(options, dict):
2413+
opts_dict = options
2414+
else:
2415+
msg = ( # type: ignore[unreachable]
2416+
f"arg 'options' has type {type(options)!r}, "
2417+
"expected one of (str | dict | None)"
2418+
)
2419+
raise ValueError(msg) # type: ignore[unreachable]
2420+
2421+
if kwargs is not None:
2422+
opts_dict = opts_dict.copy() # avoid changing original
2423+
opts_dict.update(kwargs)
2424+
2425+
return _combine_cubes(cubes, opts_dict)

0 commit comments

Comments
 (0)