Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
55 changes: 31 additions & 24 deletions esmvalcore/cmor/_fixes/cmip6/cesm2.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
"""Fixes for CESM2 model."""
from shutil import copyfile

from netCDF4 import Dataset
import numpy as np
from netCDF4 import Dataset

from ..fix import Fix
from ..shared import (add_scalar_depth_coord, add_scalar_height_coord,
add_scalar_typeland_coord, add_scalar_typesea_coord)
from ..shared import (
add_scalar_depth_coord,
add_scalar_height_coord,
add_scalar_typeland_coord,
add_scalar_typesea_coord,
)
from .gfdl_esm4 import Siconc as Addtypesi


Expand All @@ -24,27 +28,6 @@ def _fix_formula_terms(self, filepath, output_dir):
dataset.close()
return new_path

def fix_data(self, cube):
"""Fix data.

Fixed ordering of vertical coordinate.

Parameters
----------
cube: iris.cube.Cube
Input cube to fix.

Returns
-------
iris.cube.Cube

"""
(z_axis,) = cube.coord_dims(cube.coord(axis='Z', dim_coords=True))
indices = [slice(None)] * cube.ndim
indices[z_axis] = slice(None, None, -1)
cube = cube[tuple(indices)]
return cube

def fix_file(self, filepath, output_dir):
"""Fix hybrid pressure coordinate.

Expand Down Expand Up @@ -77,6 +60,30 @@ def fix_file(self, filepath, output_dir):
dataset.close()
return new_path

def fix_metadata(self, cubes):
"""Fix ``atmosphere_hybrid_sigma_pressure_coordinate``.

See discussion in #882 for more details on that.

Parameters
----------
cubes : iris.cube.CubeList
Input cubes.

Returns
-------
iris.cube.CubeList

"""
cube = self.get_cube_from_list(cubes)
lev_coord = cube.coord(var_name='lev')
a_coord = cube.coord(var_name='a')
b_coord = cube.coord(var_name='b')
lev_coord.points = a_coord.core_points() + b_coord.core_points()
lev_coord.bounds = a_coord.core_bounds() + b_coord.core_bounds()
lev_coord.units = '1'
return cubes


Cli = Cl

Expand Down
49 changes: 24 additions & 25 deletions tests/integration/cmor/_fixes/cmip6/test_cesm2.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,21 @@ def test_cl_fix_file(mock_get_filepath, tmp_path, test_data_path):


@pytest.fixture
def cl_cube():
def cl_cubes():
"""``cl`` cube."""
time_coord = iris.coords.DimCoord(
[0.0, 1.0], var_name='time', standard_name='time',
units='days since 1850-01-01 00:00:00')
a_coord = iris.coords.AuxCoord(
[0.1, 0.2, 0.1], bounds=[[0.0, 0.15], [0.15, 0.25], [0.25, 0.0]],
var_name='a', units='1')
b_coord = iris.coords.AuxCoord(
[0.9, 0.3, 0.1], bounds=[[1.0, 0.8], [0.8, 0.25], [0.25, 0.0]],
var_name='b', units='1')
lev_coord = iris.coords.DimCoord(
[0.0, 1.0, 2.0], var_name='lev',
standard_name='atmosphere_hybrid_sigma_pressure_coordinate', units='1',
attributes={'positive': 'up'})
[999.0, 99.0, 9.0], var_name='lev',
standard_name='atmosphere_hybrid_sigma_pressure_coordinate',
units='hPa', attributes={'positive': 'up'})
lat_coord = iris.coords.DimCoord(
[0.0, 1.0], var_name='lat', standard_name='latitude', units='degrees')
lon_coord = iris.coords.DimCoord(
Expand All @@ -122,30 +128,23 @@ def cl_cube():
standard_name='cloud_area_fraction_in_atmosphere_layer',
units='%',
dim_coords_and_dims=coord_specs,
aux_coords_and_dims=[(a_coord, 1), (b_coord, 1)],
)
return cube
return iris.cube.CubeList([cube])


def test_cl_fix_data(cl_cube):
"""Test ``fix_data`` for ``cl``."""
fix = Cl(None)
out_cube = fix.fix_data(cl_cube)
assert out_cube.shape == cl_cube.shape
np.testing.assert_allclose(out_cube.data,
[[[[8, 9],
[10, 11]],
[[4, 5],
[6, 7]],
[[0, 1],
[2, 3]]],
[[[20, 21],
[22, 23]],
[[16, 17],
[18, 19]],
[[12, 13],
[14, 15]]]])
np.testing.assert_allclose(out_cube.coord(var_name='lev').points,
[2.0, 1.0, 0.0])
def test_cl_fix_metadata(cl_cubes):
"""Test ``fix_metadata`` for ``cl``."""
vardef = get_var_info('CMIP6', 'Amon', 'cl')
fix = Cl(vardef)
out_cubes = fix.fix_metadata(cl_cubes)
out_cube = out_cubes.extract_cube(
'cloud_area_fraction_in_atmosphere_layer')
lev_coord = out_cube.coord(var_name='lev')
assert lev_coord.units == '1'
np.testing.assert_allclose(lev_coord.points, [1.0, 0.5, 0.2])
np.testing.assert_allclose(lev_coord.bounds,
[[1.0, 0.95], [0.95, 0.5], [0.5, 0.0]])


def test_get_cli_fix():
Expand Down
6 changes: 6 additions & 0 deletions tests/integration/cmor/_fixes/cmip6/test_cesm2_waccm.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import numpy as np
import pytest

from esmvalcore.cmor._fixes.cmip6.cesm2 import Cl as BaseCl
from esmvalcore.cmor._fixes.cmip6.cesm2 import Tas as BaseTas
from esmvalcore.cmor._fixes.cmip6.cesm2_waccm import Cl, Cli, Clw, Tas
from esmvalcore.cmor.fix import Fix
Expand All @@ -18,6 +19,11 @@ def test_get_cl_fix():
assert fix == [Cl(None)]


def test_cl_fix():
"""Test fix for ``cl``."""
assert issubclass(Cl, BaseCl)


@pytest.mark.skipif(sys.version_info < (3, 7, 6),
reason="requires python3.7.6 or newer")
@unittest.mock.patch(
Expand Down