diff --git a/improver/cli/cubelist_extract.py b/improver/cli/cubelist_extract.py new file mode 100644 index 0000000000..17d8bd5d9c --- /dev/null +++ b/improver/cli/cubelist_extract.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# (C) Crown copyright, Met Office. All rights reserved. +# +# This file is part of IMPROVER and is released under a BSD 3-Clause license. +# See LICENSE in the root of the repository for full licensing details. +"""Script to extract a cube from a cubelist""" + +from improver import cli + + +@cli.clizefy +@cli.with_output +def process(cubes: cli.inputcubelist, *, name: str): + """Extract a single cube from a cubelist whose name matches + the provided name. + + Args: + cubes (iris.cube.CubeList): + A cubelist containing exactly one cube with the provided name to + be extracted. + name (str): + The name of the cube to be extracted. + Returns: + iris.cube.Cube: + The extracted cube whose name matches the provided name. + + """ + from improver.utilities.cube_extraction import cubelist_extract + + return cubelist_extract(cubes, name) diff --git a/improver/utilities/cube_extraction.py b/improver/utilities/cube_extraction.py index c61e317bbd..8b7a7f4df4 100644 --- a/improver/utilities/cube_extraction.py +++ b/improver/utilities/cube_extraction.py @@ -9,7 +9,7 @@ import numpy as np from iris import Constraint -from iris.cube import Cube +from iris.cube import Cube, CubeList from iris.exceptions import CoordinateNotFoundError from improver import BasePlugin @@ -346,6 +346,19 @@ def thin_cube(cube: Cube, thinning_dict: Dict[str, int]) -> Cube: return cube[tuple(slices)] +def cubelist_extract(cubes: CubeList, name: str): + """Extract a cube from a CubeList based on provided name. + Args: + cubes: + A CubeList. + name: + Name of the cube to be extracted. + Returns: + A single cube matching the input name. + """ + return cubes.extract_cube(name) + + class ExtractLevel(BasePlugin): """ Class for extracting a pressure or height surface from data-on-levels. diff --git a/improver_tests/acceptance/SHA256SUMS b/improver_tests/acceptance/SHA256SUMS index 18f5114669..8db958a2cd 100644 --- a/improver_tests/acceptance/SHA256SUMS +++ b/improver_tests/acceptance/SHA256SUMS @@ -331,6 +331,8 @@ ae2f673bf29b926cac46c3a578a8e1842cce19881f8fe479cba3f51f0d474951 ./copy-attribu d3efbc6014743793fafed512a8017a7b75e4f0ffa7fd202cd4f1b4a1086b2583 ./create-grid-with-halo/basic/kgo.nc fee00437131d2367dc317e5b0fff44e65e03371b8f096bf1ac0d4cc7253693c9 ./create-grid-with-halo/basic/source_grid.nc bf7e42be7897606682c3ecdaeb27bf3d3b6ab13a9a88b46c88ae6e92801c6245 ./create-grid-with-halo/halo_size/kgo.nc +55ba8a8ca8b5eee667d37fe8ec4a653caddea27f19ea290397428a487eb13ca0 ./cubelist-extract/input_cubelist.nc +33c7e0cf46ac62ead74ffde502ee28076a59550474fb3872c3e22083c4bd3cc3 ./cubelist-extract/kgo.nc fe00aadb6854f44d765b40bb6608c23f4eb4f10193c96f43f207db0590739dab ./enforce-consistent-forecasts/double_bound_percentile_kgo.nc 51f9ff2c8e6cad54d04d6323c654ce25b812bea3ba6b0d85df21c19731c580fc ./enforce-consistent-forecasts/percentile_forecast.nc e210bf956dd3574eda3a64fdc3371ab16f85048ca120a3823e90d751d2325c46 ./enforce-consistent-forecasts/percentile_reference.nc diff --git a/improver_tests/acceptance/test_cubelist_extract.py b/improver_tests/acceptance/test_cubelist_extract.py new file mode 100644 index 0000000000..0f62581074 --- /dev/null +++ b/improver_tests/acceptance/test_cubelist_extract.py @@ -0,0 +1,26 @@ +# (C) Crown copyright, Met Office. All rights reserved. +# +# This file is part of IMPROVER and is released under a BSD 3-Clause license. +# See LICENSE in the root of the repository for full licensing details. +""" +Tests for the cubelist-extract CLI +""" + +import pytest + +from . import acceptance as acc + +pytestmark = [pytest.mark.acc, acc.skip_if_kgo_missing] +CLI = acc.cli_name_with_dashes(__file__) +run_cli = acc.run_cli(CLI) + + +def test_basic(tmp_path): + """Test basic extraction""" + kgo_dir = acc.kgo_root() / "cubelist-extract" + kgo_path = kgo_dir / "kgo.nc" + input_path = kgo_dir / "input_cubelist.nc" + output_path = tmp_path / "output.nc" + args = [input_path, "--name=grid_eastward_wind", "--output", output_path] + run_cli(args) + acc.compare(output_path, kgo_path) diff --git a/improver_tests/utilities/cube_extraction/test_cube_extraction.py b/improver_tests/utilities/cube_extraction/test_cube_extraction.py index 75ed1f2dd2..0712b96f08 100644 --- a/improver_tests/utilities/cube_extraction/test_cube_extraction.py +++ b/improver_tests/utilities/cube_extraction/test_cube_extraction.py @@ -20,6 +20,7 @@ from improver.utilities.cube_extraction import ( apply_extraction, create_constraint, + cubelist_extract, extract_subcube, parse_constraint_list, ) @@ -98,6 +99,20 @@ def set_up_uk_gridded_cube(): ) +def test_cubelist_extract(): + """Test the extraction of a single cube from a cube list.""" + + cube1 = set_up_variable_cube( + np.empty((3, 3), dtype=np.float32), name="temperature", units="K" + ) + cube2 = set_up_variable_cube( + np.empty((3, 3), dtype=np.float32), name="precipitation_rate", units="mm h-1" + ) + cube_list = iris.cube.CubeList([cube1, cube2]) + result = cubelist_extract(cube_list, "temperature") + assert result == cube1 + + class Test_create_constraint(IrisTest): """Test the creation of constraints that allow for floating point comparisons."""