Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes in support of configuration execution which call plugins directly (i.e. not via CLI) #2036

Merged
merged 5 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
TEST: Negative power numpy int
  • Loading branch information
cpelley committed Oct 14, 2024
commit 2c5cd63308b6b5e376a67f1d69bf9ace3c71fd23
11 changes: 6 additions & 5 deletions improver/utilities/copy_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
#
# 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.
from typing import List, Tuple, Union
from typing import List, Union

from iris.cube import Cube, CubeList

from improver import BasePlugin
from improver.metadata.amend import amend_attributes
from improver.utilities.common_input_handle import as_cube, as_cubelist
from improver.utilities.common_input_handle import as_cubelist


class CopyAttributes(BasePlugin):
Expand All @@ -25,8 +25,7 @@ def __init__(self, attributes: List):
"""
self.attributes = attributes

def process(
self, *cubes: Union[Cube, CubeList]) -> Union[Cube, CubeList]:
def process(self, *cubes: Union[Cube, CubeList]) -> Union[Cube, CubeList]:
"""
Copy attribute values from template_cube to cube, overwriting any existing values.

Expand All @@ -42,7 +41,9 @@ def process(
"""
cubes_proc = as_cubelist(*cubes)
if len(cubes_proc) < 2:
raise RuntimeError(f"At least two cubes are required for this operation, got {len(cubes_proc)}")
raise RuntimeError(
f"At least two cubes are required for this operation, got {len(cubes_proc)}"
)
template_cube = cubes_proc.pop()

for cube in cubes_proc:
Expand Down
6 changes: 4 additions & 2 deletions improver/utilities/cube_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ def fill_invalid(self, cube: Cube):
Args:
cube:
Cube of variable on levels (3D) (modified in-place).
"""
"""
if np.isfinite(cube.data).all() and not np.ma.is_masked(cube.data):
return
data = np.ma.masked_invalid(cube.data)
Expand All @@ -413,7 +413,9 @@ def fill_invalid(self, cube: Cube):
# We don't really care so long as it is non-zero and has the same sign.
increasing_order = np.all(np.diff(cube.coord(self.coordinate).points) > 0)
sign = 1 if self.positive_correlation == increasing_order else -1
v_increment = sign * 10 ** (-int(cube.attributes.get("least_significant_digit", 2)))
v_increment = sign * 10 ** (
-int(cube.attributes.get("least_significant_digit", 2))
)
self._one_way_fill(
data, coordinate_axis, coordinate_points, v_increment, reverse=True
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ def test_as_cubelist_called(mock_as_cubelist):
)
except HaltExecution:
pass
mock_as_cubelist.assert_called_once_with(sentinel.cube0, sentinel.cube1, sentinel.template_cube)
mock_as_cubelist.assert_called_once_with(
sentinel.cube0, sentinel.cube1, sentinel.template_cube
)


def test_copy_attributes_multi_input():
Expand Down
16 changes: 16 additions & 0 deletions improver_tests/utilities/cube_extraction/test_ExtractLevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,22 @@ def test_basic(
cube_shape_check_without_realizations(result)


@pytest.mark.parametrize("least_significant_digit", (None, 2, np.int32(2)))
def test_fill_invalid_supported_lsd_types(
temperature_on_height_levels, least_significant_digit
):
"""
Ensure performing power of negative python int/numpy int least_significant_digit supported.
"""
cube = temperature_on_height_levels
cube.data = np.ma.MaskedArray(cube.data, mask=False)
cube.data.mask[0, 0, 0, 0] = True
if least_significant_digit is not None:
cube.attributes["least_significant_digit"] = least_significant_digit
plugin = ExtractLevel(value_of_level=277, positive_correlation=True)
plugin(cube)


@pytest.mark.parametrize(
"index, expected",
(
Expand Down
Loading