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: 52 additions & 3 deletions esmvalcore/cmor/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,10 @@ def _check_multiple_coords_same_stdname(self):

def _check_dim_names(self):
"""Check dimension names."""
for (_, coordinate) in self._cmor_var.coordinates.items():
cmor_var_coordinates = self._cmor_var.coordinates.copy()
for (key, coordinate) in cmor_var_coordinates.items():
if coordinate.generic_level:
continue
self._check_generic_level_dim_names(key, coordinate)
else:
try:
cube_coord = self._cube.coord(var_name=coordinate.out_name)
Expand Down Expand Up @@ -383,11 +384,59 @@ def _check_dim_names(self):
self.report_error(
self._does_msg, coordinate.name, 'exist')

def _check_generic_level_dim_names(self, key, coordinate):
if coordinate.generic_lev_coords:
for coord in coordinate.generic_lev_coords.values():
try:
cube_coord = self._cube.coord(
var_name=coord.out_name
)
coordinate.out_name = coord.out_name
if cube_coord.standard_name == coord.standard_name:
coordinate.standard_name = coord.standard_name
coordinate.name = coord.name
except iris.exceptions.CoordinateNotFoundError:
try:
cube_coord = self._cube.coord(
var_name=coord.standard_name
)
coordinate.standard_name = coord.standard_name
coordinate.name = coord.name
except iris.exceptions.CoordinateNotFoundError:
pass
if coordinate.standard_name:
if not coordinate.out_name:
self.report_error(
f'Coordinate {coordinate.name} '
'has wrong var_name.',
)
level = coordinate.generic_lev_coords[coordinate.name]
level.generic_level = True
level.generic_lev_coords = self._cmor_var.coordinates[
key].generic_lev_coords
self._cmor_var.coordinates[key] = level
self.report_debug_message(
f'Generic level coordinate {key} '
'will be checked against '
f'{coordinate.name} coordinate information'
)
else:
if coordinate.out_name:
self.report_critical(
f'Coordinate {coordinate.name} '
'has wrong standard_name '
'or is not set.',
)
else:
self.report_critical(
self._does_msg, coordinate.name, 'exist'
)

def _check_coords(self):
"""Check coordinates."""
for coordinate in self._cmor_var.coordinates.values():
# Cannot check generic_level coords as no CMOR information
if coordinate.generic_level:
if coordinate.generic_level and not coordinate.out_name:
continue
var_name = coordinate.out_name

Expand Down
9 changes: 8 additions & 1 deletion esmvalcore/cmor/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,10 @@ def _assign_dimensions(self, var, generic_levels):
if dimension in generic_levels:
coord = CoordinateInfo(dimension)
coord.generic_level = True
coord.axis = 'Z'
for name in self.coords:
generic_level = self.coords[name].generic_lev_name
if dimension in [generic_level]:
coord.generic_lev_coords[name] = self.coords[name]
else:
try:
coord = self.coords[dimension]
Expand Down Expand Up @@ -577,6 +580,7 @@ def __init__(self, name):
super(CoordinateInfo, self).__init__()
self.name = name
self.generic_level = False
self.generic_lev_coords = {}

self.axis = ""
"""Axis"""
Expand Down Expand Up @@ -606,6 +610,8 @@ def __init__(self, name):
"""Maximum allowed value"""
self.must_have_bounds = ""
"""Whether bounds are required on this dimension"""
self.generic_lev_name = ""
"""Generic level name"""

def read_json(self, json_data):
"""
Expand Down Expand Up @@ -634,6 +640,7 @@ def read_json(self, json_data):
self.valid_max = self._read_json_variable('valid_max')
self.requested = self._read_json_list_variable('requested')
self.must_have_bounds = self._read_json_variable('must_have_bounds')
self.generic_lev_name = self._read_json_variable('generic_level_name')


class CMIP5Info(InfoBase):
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/cmor/test_cmor_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def __init__(self, name):
self.stored_direction = "increasing"
self.must_have_bounds = "yes"
self.requested = []
self.generic_lev_coords = {}
self.generic_lev_name = ""

valid_limits = {'lat': ('-90', '90'), 'lon': ('0', '360')}
if name in valid_limits:
Expand Down Expand Up @@ -292,6 +294,20 @@ def test_rank_unstructured_grid(self):
self.cube.add_aux_coord(new_lat, 1)
self._check_cube()

def test_bad_generic_level(self):
"""Test check fails in metadata if generic level coord
has wrong var_name."""
depth_coord = CoordinateInfoMock('depth')
depth_coord.axis = 'Z'
depth_coord.generic_lev_name = 'olevel'
depth_coord.out_name = 'lev'
depth_coord.name = 'depth_coord'
depth_coord.long_name = 'ocean depth coordinate'
self.var_info.coordinates['depth'].generic_lev_coords = {
'depth_coord': depth_coord}
self.var_info.coordinates['depth'].out_name = ""
self._check_fails_in_metadata()

def test_check_bad_var_standard_name_strict_flag(self):
"""Test check fails for a bad variable standard_name with
--cmor-check strict."""
Expand Down