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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions esmvalcore/cmor/_fixes/cmip5/miroc_esm.py
Original file line number Diff line number Diff line change
@@ -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):
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
Original file line number Diff line number Diff line change
@@ -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',
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