|
15 | 15 | import os.path |
16 | 16 | import sys |
17 | 17 | import tempfile |
18 | | -from typing import Literal |
| 18 | +from typing import TYPE_CHECKING, List, Literal |
19 | 19 | from warnings import warn |
20 | 20 |
|
21 | 21 | import cf_units |
|
31 | 31 | import iris.exceptions |
32 | 32 | import iris.warnings |
33 | 33 |
|
| 34 | +if TYPE_CHECKING: |
| 35 | + from iris.cube import Cube, CubeList |
| 36 | + |
34 | 37 |
|
35 | 38 | def broadcast_to_shape(array, shape, dim_map, chunks=None): |
36 | 39 | """Broadcast an array to a given shape. |
@@ -2343,3 +2346,80 @@ def _print_xml(doc): |
2343 | 2346 | """ |
2344 | 2347 | result = doc.toprettyxml(indent=" ") |
2345 | 2348 | 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