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
29 changes: 27 additions & 2 deletions esmvalcore/cmor/_fixes/cmip6/bcc_csm2_mr.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,41 @@ class Tos(BaseTos):

def fix_metadata(self, cubes):
"""Rename ``var_name`` of 1D-``latitude`` and 1D-``longitude``.

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

Returns
-------
iris.cube.CubeList
"""
cube = self.get_cube_from_list(cubes)
lat_coord = cube.coord('latitude', dimensions=(1, ))
lon_coord = cube.coord('longitude', dimensions=(2, ))
lat_coord.standard_name = None
lat_coord.long_name = 'grid_latitude'
lat_coord.var_name = 'i'
lat_coord.units = '1'
lon_coord.standard_name = None
lon_coord.long_name = 'grid_longitude'
lon_coord.var_name = 'j'
lon_coord.units = '1'
lon_coord.circular = False
return cubes


class Siconc(BaseTos):
"""Fixes for siconc."""

def fix_metadata(self, cubes):
"""Rename ``var_name`` of 1D-``latitude`` and 1D-``longitude``.
Parameters
----------
cubes : iris.cube.CubeList
Input cubes.
Returns
-------
iris.cube.CubeList
"""
cube = self.get_cube_from_list(cubes)
lat_coord = cube.coord('latitude', dimensions=(1, ))
Expand Down
51 changes: 50 additions & 1 deletion esmvalcore/cmor/_fixes/cmip6/cesm2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
from shutil import copyfile

from netCDF4 import Dataset
import numpy as np

from ..fix import Fix
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


class Cl(Fix):
Expand Down Expand Up @@ -107,7 +109,10 @@ class Tas(Fix):
"""Fixes for tas."""

def fix_metadata(self, cubes):
"""Add height (2m) coordinate.
"""
Add height (2m) coordinate.

Fix latitude_bounds and longitude_bounds data type and round to 4 d.p.

Parameters
----------
Expand All @@ -121,6 +126,19 @@ def fix_metadata(self, cubes):
"""
cube = self.get_cube_from_list(cubes)
add_scalar_height_coord(cube)

for cube in cubes:
latitude = cube.coord('latitude')
if latitude.bounds is None:
latitude.guess_bounds()
latitude.bounds = latitude.bounds.astype(np.float64)
latitude.bounds = np.round(latitude.bounds, 4)
longitude = cube.coord('longitude')
if longitude.bounds is None:
longitude.guess_bounds()
longitude.bounds = longitude.bounds.astype(np.float64)
longitude.bounds = np.round(longitude.bounds, 4)

return cubes


Expand Down Expand Up @@ -164,3 +182,34 @@ def fix_metadata(self, cubes):
cube = self.get_cube_from_list(cubes)
add_scalar_typesea_coord(cube)
return cubes


class Tos(Fix):
"""Fixes for tos."""

def fix_metadata(self, cubes):
"""
Round times to 1 d.p. for monthly means.

Required to get hist-GHG and ssp245-GHG Omon tos to concatenate.

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

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

"""
cube = self.get_cube_from_list(cubes)

for cube in cubes:
if cube.attributes['mipTable'] == 'Omon':
cube.coord('time').points = \
np.round(cube.coord('time').points, 1)
return cubes


Siconc = Addtypesi
8 changes: 8 additions & 0 deletions esmvalcore/cmor/_fixes/cmip6/fgoals_g3.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Fixes for FGOALS-g3 model."""
from ..cmip5.fgoals_g2 import Cl as BaseCl
from ..common import OceanFixGrid


Cl = BaseCl

Expand All @@ -8,3 +10,9 @@


Clw = BaseCl


Tos = OceanFixGrid


Siconc = OceanFixGrid
32 changes: 32 additions & 0 deletions esmvalcore/cmor/_fixes/cmip6/gfdl_esm4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Fixes for GFDL-ESM4 model."""
import iris
from ..fix import Fix


class Siconc(Fix):
"""Fixes for siconc."""

def fix_metadata(self, cubes):
"""
Fix missing type.

Parameters
----------
cubes: iris CubeList
List of cubes to fix

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

"""
typesi = iris.coords.AuxCoord(
'siconc',
standard_name='area_type',
long_name='Sea Ice area type',
var_name='type',
units='1',
bounds=None)
for cube in cubes:
cube.add_aux_coord(typesi)
return cubes
33 changes: 33 additions & 0 deletions esmvalcore/cmor/_fixes/cmip6/noresm2_lm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Fixes for NorESM2-LM model."""
import numpy as np
from ..fix import Fix


class Siconc(Fix):
"""Fixes for siconc."""

def fix_metadata(self, cubes):
"""
Fix metadata.

Some coordinate points vary for different files of this dataset (for
different time range). This fix removes these inaccuracies by rounding
the coordinates.

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

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

"""
for cube in cubes:
latitude = cube.coord('latitude')
latitude.bounds = np.round(latitude.bounds, 4)
longitude = cube.coord('longitude')
longitude.bounds = np.round(longitude.bounds, 4)

return cubes
95 changes: 95 additions & 0 deletions esmvalcore/cmor/_fixes/common.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Common fixes used for multiple datasets."""
import iris
import numpy as np
from scipy.ndimage import map_coordinates

from .fix import Fix
from .shared import add_plev_from_altitude, fix_bounds
Expand Down Expand Up @@ -101,3 +103,96 @@ def fix_metadata(self, cubes):
cube.coord(var_name='ps').attributes = {}

return iris.cube.CubeList([cube])


class OceanFixGrid(Fix):
"""Fixes for tos, siconc in FGOALS-g3."""

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

Calculate missing latitude/longitude boundaries using interpolation.
Based on a similar fix for BCC-CSM2-MR.

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

Returns
-------
iris.cube.Cube
"""
rlat = cube.coord('grid_latitude').points
rlon = cube.coord('grid_longitude').points

# Guess coordinate bounds in rlat, rlon (following BCC-CSM2-MR-1).
rlat_idx_bnds = np.zeros((len(rlat), 2))
rlat_idx_bnds[:, 0] = np.arange(len(rlat)) - 0.5
rlat_idx_bnds[:, 1] = np.arange(len(rlat)) + 0.5
rlat_idx_bnds[0, 0] = 0.
rlat_idx_bnds[len(rlat) - 1, 1] = len(rlat)
rlon_idx_bnds = np.zeros((len(rlon), 2))
rlon_idx_bnds[:, 0] = np.arange(len(rlon)) - 0.5
rlon_idx_bnds[:, 1] = np.arange(len(rlon)) + 0.5

# Calculate latitude/longitude vertices by interpolation
lat_vertices = []
lon_vertices = []
for (i, j) in [(0, 0), (0, 1), (1, 1), (1, 0)]:
(rlat_v, rlon_v) = np.meshgrid(rlat_idx_bnds[:, i],
rlon_idx_bnds[:, j],
indexing='ij')
lat_vertices.append(
map_coordinates(cube.coord('latitude').points,
[rlat_v, rlon_v],
mode='nearest'))
lon_vertices.append(
map_coordinates(cube.coord('longitude').points,
[rlat_v, rlon_v],
mode='wrap'))
lat_vertices = np.array(lat_vertices)
lon_vertices = np.array(lon_vertices)
lat_vertices = np.moveaxis(lat_vertices, 0, -1)
lon_vertices = np.moveaxis(lon_vertices, 0, -1)

# Copy vertices to cube
cube.coord('latitude').bounds = lat_vertices
cube.coord('longitude').bounds = lon_vertices
return cube

def fix_metadata(self, cubes):
"""
Rename ``var_name`` of 1D-``latitude`` and 1D-``longitude``.

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

Returns
-------
iris.cube.CubeList
"""
cube = self.get_cube_from_list(cubes)
lat_coord = cube.coord('cell index along second dimension',
dimensions=(1, ))
lon_coord = cube.coord('cell index along first dimension',
dimensions=(2, ))
lat_coord.standard_name = None
lat_coord.long_name = 'grid_latitude'
lat_coord.var_name = 'i'
lat_coord.units = '1'
lon_coord.standard_name = None
lon_coord.long_name = 'grid_longitude'
lon_coord.var_name = 'j'
lon_coord.units = '1'
lon_coord.circular = False
# FGOALS-g3 data contain latitude and longitude data set to
# >1e30 in some places. Set to 0. to avoid problem in check.py.
cube.coord('latitude').points[cube.coord('latitude').points > 1000.]\
= 0.
cube.coord('longitude').points[cube.coord('longitude').points > 1000.]\
= 0.
return cubes
Loading