Skip to content

Commit 88be3be

Browse files
committed
Add cubelist combine methods.
1 parent 7ca4d8e commit 88be3be

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

lib/iris/cube.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,34 @@ def concatenate(
634634
check_derived_coords=check_derived_coords,
635635
)
636636

637+
def combine(self, options: str | dict | None = None, **kwargs) -> CubeList:
638+
from iris.util import combine_cubes
639+
640+
return combine_cubes(self, options, **kwargs)
641+
642+
def combine_cube(self, options: str | dict | None = None, **kwargs) -> CubeList:
643+
result = self.combine()
644+
n_cubes = len(result)
645+
if n_cubes != 1:
646+
from iris.util import _combine_options_asdict
647+
648+
opts_dict = _combine_options_asdict(options)
649+
merge_concat_sequence = opts_dict.get("merge_concat_sequence")
650+
is_merge = (
651+
not isinstance(merge_concat_sequence, str)
652+
or len(merge_concat_sequence) < 0
653+
or not merge_concat_sequence.endswith("m")
654+
)
655+
err_type = (
656+
iris.exceptions.MergeError
657+
if is_merge
658+
else iris.exceptions.ConcatenateError
659+
)
660+
msg = f"'combine' operation yielded {n_cubes} cubes, expected exactly 1."
661+
raise err_type(msg)
662+
663+
return result
664+
637665
def realise_data(self):
638666
"""Fetch 'real' data for all cubes, in a shared calculation.
639667

lib/iris/util.py

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,33 @@ def _print_xml(doc):
23482348
return result.replace("&#10;", "\n")
23492349

23502350

2351+
def _combine_options_asdict(options: str | dict | None) -> dict:
2352+
"""Convert any valid combine options into an options dictionary."""
2353+
from iris import LOAD_POLICY
2354+
2355+
if options is None:
2356+
opts_dict = LOAD_POLICY.settings()
2357+
elif isinstance(options, dict):
2358+
opts_dict = options
2359+
elif isinstance(options, str):
2360+
if options in LOAD_POLICY.SETTINGS:
2361+
opts_dict = LOAD_POLICY.SETTINGS[options]
2362+
else:
2363+
msg = (
2364+
"Unrecognised settings name : expected one of "
2365+
f"{tuple(LOAD_POLICY.SETTINGS)}."
2366+
)
2367+
raise ValueError(msg)
2368+
else:
2369+
msg = ( # type: ignore[unreachable]
2370+
f"arg 'options' has type {type(options)!r}, "
2371+
"expected one of (str | dict | None)"
2372+
)
2373+
raise ValueError(msg) # type: ignore[unreachable]
2374+
2375+
return opts_dict
2376+
2377+
23512378
def combine_cubes(
23522379
cubes: List[Cube],
23532380
options: str | dict | None = None,
@@ -2450,30 +2477,9 @@ def testcube(timepts):
24502477
24512478
"""
24522479
# TODO: somehow, provide a real + useful working code example
2453-
2454-
from iris import LOAD_POLICY, CombineOptions
24552480
from iris._combine import _combine_cubes
24562481

2457-
if options is None:
2458-
opts_dict = LOAD_POLICY.settings()
2459-
elif isinstance(options, str):
2460-
if options in CombineOptions.SETTINGS:
2461-
opts_dict = CombineOptions.SETTINGS[options]
2462-
else:
2463-
msg = (
2464-
"Unrecognised settings name : expected one of "
2465-
f"{tuple(CombineOptions.SETTINGS)}."
2466-
)
2467-
raise ValueError(msg)
2468-
elif isinstance(options, dict):
2469-
opts_dict = options
2470-
else:
2471-
msg = ( # type: ignore[unreachable]
2472-
f"arg 'options' has type {type(options)!r}, "
2473-
"expected one of (str | dict | None)"
2474-
)
2475-
raise ValueError(msg) # type: ignore[unreachable]
2476-
2482+
opts_dict = _combine_options_asdict(options)
24772483
if kwargs is not None:
24782484
opts_dict = opts_dict.copy() # avoid changing original
24792485
opts_dict.update(kwargs)

0 commit comments

Comments
 (0)