diff --git a/esmvalcore/cmor/_fixes/cmip6/kiost_esm.py b/esmvalcore/cmor/_fixes/cmip6/kiost_esm.py index 518a82e541..77ab4805e5 100644 --- a/esmvalcore/cmor/_fixes/cmip6/kiost_esm.py +++ b/esmvalcore/cmor/_fixes/cmip6/kiost_esm.py @@ -1,4 +1,6 @@ """Fixes for KIOST-ESM model.""" +from dask import array as da + from ..common import SiconcFixScalarCoord from ..fix import Fix from ..shared import add_scalar_height_coord @@ -17,7 +19,8 @@ def fix_metadata(self, cubes): Returns ------- - iris.cube.Cube + iris.cube.Cubes + Fixed cubes. """ cube = self.get_cube_from_list(cubes) add_scalar_height_coord(cube, 2.0) @@ -45,7 +48,8 @@ def fix_metadata(self, cubes): Returns ------- - iris.cube.Cube + iris.cube.Cubes + Fixed cubes. """ cube = self.get_cube_from_list(cubes) add_scalar_height_coord(cube, 10.0) @@ -60,4 +64,23 @@ class Vas(SfcWind): """Fixes for vas.""" -Siconc = SiconcFixScalarCoord +class Siconc(SiconcFixScalarCoord): + """Fixes for siconc.""" + + def fix_data(self, cube): + """Fix data. + + Fix missing values. + + Parameters + ---------- + cube: iris.cube.Cube + Input cube. + + Returns + ------- + iris.cube.Cube + Fixed cube. + """ + cube.data = da.ma.masked_invalid(cube.core_data()) + return cube diff --git a/tests/integration/cmor/_fixes/cmip6/test_kiost_esm.py b/tests/integration/cmor/_fixes/cmip6/test_kiost_esm.py index 41de6089c5..9b460db15a 100644 --- a/tests/integration/cmor/_fixes/cmip6/test_kiost_esm.py +++ b/tests/integration/cmor/_fixes/cmip6/test_kiost_esm.py @@ -1,13 +1,12 @@ """Test fixes for KIOST-ESM.""" import iris +import numpy as np import pytest from cf_units import Unit +from iris.coords import DimCoord +from iris.cube import Cube, CubeList -from esmvalcore.cmor._fixes.cmip6.kiost_esm import ( - SfcWind, - Siconc, - Tas, -) +from esmvalcore.cmor._fixes.cmip6.kiost_esm import SfcWind, Siconc, Tas from esmvalcore.cmor._fixes.common import SiconcFixScalarCoord from esmvalcore.cmor._fixes.fix import Fix from esmvalcore.cmor.table import get_var_info @@ -15,60 +14,60 @@ @pytest.fixture def sfcwind_cubes(): - correct_lat_coord = iris.coords.DimCoord([0.0], - var_name='lat', - standard_name='latitude') - wrong_lat_coord = iris.coords.DimCoord([0.0], - var_name='latitudeCoord', - standard_name='latitude') - correct_lon_coord = iris.coords.DimCoord([0.0], - var_name='lon', - standard_name='longitude') - wrong_lon_coord = iris.coords.DimCoord([0.0], - var_name='longitudeCoord', - standard_name='longitude') - correct_cube = iris.cube.Cube( + correct_lat_coord = DimCoord([0.0], + var_name='lat', + standard_name='latitude') + wrong_lat_coord = DimCoord([0.0], + var_name='latitudeCoord', + standard_name='latitude') + correct_lon_coord = DimCoord([0.0], + var_name='lon', + standard_name='longitude') + wrong_lon_coord = DimCoord([0.0], + var_name='longitudeCoord', + standard_name='longitude') + correct_cube = Cube( [[10.0]], var_name='sfcWind', dim_coords_and_dims=[(correct_lat_coord, 0), (correct_lon_coord, 1)], ) - wrong_cube = iris.cube.Cube( + wrong_cube = Cube( [[10.0]], var_name='ta', dim_coords_and_dims=[(wrong_lat_coord, 0), (wrong_lon_coord, 1)], attributes={'parent_time_units': 'days since 0000-00-00 (noleap)'}, ) - scalar_cube = iris.cube.Cube(0.0, var_name='ps') - return iris.cube.CubeList([correct_cube, wrong_cube, scalar_cube]) + scalar_cube = Cube(0.0, var_name='ps') + return CubeList([correct_cube, wrong_cube, scalar_cube]) @pytest.fixture def tas_cubes(): - correct_lat_coord = iris.coords.DimCoord([0.0], - var_name='lat', - standard_name='latitude') - wrong_lat_coord = iris.coords.DimCoord([0.0], - var_name='latitudeCoord', - standard_name='latitude') - correct_lon_coord = iris.coords.DimCoord([0.0], - var_name='lon', - standard_name='longitude') - wrong_lon_coord = iris.coords.DimCoord([0.0], - var_name='longitudeCoord', - standard_name='longitude') - correct_cube = iris.cube.Cube( + correct_lat_coord = DimCoord([0.0], + var_name='lat', + standard_name='latitude') + wrong_lat_coord = DimCoord([0.0], + var_name='latitudeCoord', + standard_name='latitude') + correct_lon_coord = DimCoord([0.0], + var_name='lon', + standard_name='longitude') + wrong_lon_coord = DimCoord([0.0], + var_name='longitudeCoord', + standard_name='longitude') + correct_cube = Cube( [[10.0]], var_name='tas', dim_coords_and_dims=[(correct_lat_coord, 0), (correct_lon_coord, 1)], ) - wrong_cube = iris.cube.Cube( + wrong_cube = Cube( [[10.0]], var_name='ta', dim_coords_and_dims=[(wrong_lat_coord, 0), (wrong_lon_coord, 1)], attributes={'parent_time_units': 'days since 0000-00-00 (noleap)'}, ) - scalar_cube = iris.cube.Cube(0.0, var_name='ps') - return iris.cube.CubeList([correct_cube, wrong_cube, scalar_cube]) + scalar_cube = Cube(0.0, var_name='ps') + return CubeList([correct_cube, wrong_cube, scalar_cube]) def test_get_sfcwind_fix(): @@ -110,7 +109,20 @@ def test_get_siconc_fix(): def test_siconc_fix(): """Test fix for ``siconc``.""" - assert Siconc is SiconcFixScalarCoord + assert issubclass(Siconc, SiconcFixScalarCoord) + + +def test_siconc_fix_data(): + """Test fix for ``siconc``.""" + vardef = get_var_info('CMIP6', 'SImon', 'siconc') + fix = Siconc(vardef) + + cube = Cube([0.0, np.nan, 1.0], var_name='siconc') + assert not np.ma.is_masked(cube.data) + + out_cube = fix.fix_data(cube) + np.testing.assert_array_almost_equal(out_cube.data, [0.0, np.nan, 1.0]) + np.testing.assert_array_equal(out_cube.data.mask, [False, True, False]) def test_get_tas_fix():