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

Fixed time coordinate of MIROC-ESM #1188

Merged
merged 4 commits into from Jun 30, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 23 additions & 2 deletions esmvalcore/cmor/_fixes/cmip5/miroc_esm.py
@@ -1,12 +1,13 @@
"""Fixes for MIROC-ESM model."""

import numpy as np
from cf_units import Unit
from iris.coords import DimCoord
from iris.exceptions import CoordinateNotFoundError

from ..common import ClFixHybridPressureCoord
from ..fix import Fix


Cl = ClFixHybridPressureCoord


Expand Down Expand Up @@ -65,7 +66,8 @@ def fix_metadata(self, cubes):
"""
Fix metadata.

Fixes error in air_pressure coordinate, sometimes called AR5PL35
Fixes error in air_pressure coordinate, sometimes called AR5PL35, and
error in time coordinate.

Parameters
----------
Expand All @@ -78,6 +80,7 @@ def fix_metadata(self, cubes):

"""
for cube in cubes:
# Fix air_pressure
try:
old = cube.coord('AR5PL35')
dims = cube.coord_dims(old)
Expand All @@ -91,4 +94,22 @@ def fix_metadata(self, cubes):
except CoordinateNotFoundError:
pass

# Fix time for files that contain year < 1 (which is not allowed)
if cube.coords('time'):
expected_time_units = Unit('days since 1950-1-1 00:00:00',
calendar='gregorian')
if cube.coord('time').units != expected_time_units:
continue
if cube.coord('time').bounds is None:
continue

# Only apply fix if there is a year < 1 in the first element
# of the time bounds (-711860.5 days from 1950-01-01 is <
# year 1)
if np.isclose(cube.coord('time').bounds[0][0], -711860.5):
schlunma marked this conversation as resolved.
Show resolved Hide resolved
new_points = cube.coord('time').points.copy() + 3.5
new_bounds = cube.coord('time').bounds.copy() + 3.5
cube.coord('time').points = new_points
cube.coord('time').bounds = new_bounds

return cubes
41 changes: 41 additions & 0 deletions tests/integration/cmor/_fixes/cmip5/test_miroc_esm.py
@@ -1,6 +1,7 @@
"""Test MIROC-ESM fixes."""
import unittest

import numpy as np
from cf_units import Unit
from iris.coords import DimCoord
from iris.cube import Cube
Expand Down Expand Up @@ -79,6 +80,22 @@ def setUp(self):
calendar='gregorian')), 0)
self.cube.add_dim_coord(DimCoord([0, 1], long_name='AR5PL35'), 1)

time_units = Unit('days since 1950-1-1 00:00:00', calendar='gregorian')

# Setup wrong time coordinate that is present in some files
# (-711860.5 days from 1950-01-01 is < year 1)
time_coord = DimCoord(
[-711845.0, -711814.0],
bounds=[[-711860.5, -711829.5], [-711829.5, -711800.0]],
var_name='time',
schlunma marked this conversation as resolved.
Show resolved Hide resolved
standard_name='time',
long_name='time',
units=time_units,
)
self.cube_with_wrong_time = Cube([0.0, 1.0], var_name='co2',
units='ppm',
dim_coords_and_dims=[(time_coord, 0)])

self.fix = AllVars(None)

def test_get(self):
Expand All @@ -100,3 +117,27 @@ def test_fix_metadata_no_plev(self):
cube = self.fix.fix_metadata([self.cube])[0]
with self.assertRaises(CoordinateNotFoundError):
cube.coord('air_pressure')

def test_fix_metadata_correct_time(self):
"""Test fix for time."""
fixed_cube = self.fix.fix_metadata([self.cube])[0]
time_coord = fixed_cube.coord('time')
np.testing.assert_allclose(time_coord.points, [0, 1])
assert time_coord.bounds is None

def test_fix_metadata_wrong_time(self):
"""Test fix for time."""
fixed_cube = self.fix.fix_metadata([self.cube_with_wrong_time])[0]
time_coord = fixed_cube.coord('time')
np.testing.assert_allclose(time_coord.points, [-711841.5, -711810.5])
np.testing.assert_allclose(
time_coord.bounds,
[[-711857.0, -711826.0], [-711826.0, -711796.5]])

def test_fix_metadata_wrong_time_no_bounds(self):
"""Test fix for time."""
self.cube_with_wrong_time.coord('time').bounds = None
fixed_cube = self.fix.fix_metadata([self.cube_with_wrong_time])[0]
time_coord = fixed_cube.coord('time')
np.testing.assert_allclose(time_coord.points, [-711845.0, -711814.0])
assert time_coord.bounds is None