Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
65 changes: 2 additions & 63 deletions esmvalcore/cmor/_fixes/cmip5/bcc_csm1_1.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,7 @@
"""Fixes for bcc-csm1-1."""
import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
from scipy.ndimage import map_coordinates

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

from ..common import ClFixHybridPressureCoord, OceanFixGrid

Cl = ClFixHybridPressureCoord


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

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

Calculate missing latitude/longitude boundaries using interpolation.

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

# Transform grid latitude/longitude to array indices [0, 1, 2, ...]
rlat_to_idx = InterpolatedUnivariateSpline(rlat,
np.arange(len(rlat)),
k=1)
rlon_to_idx = InterpolatedUnivariateSpline(rlon,
np.arange(len(rlon)),
k=1)
rlat_idx_bnds = rlat_to_idx(cube.coord('grid_latitude').bounds)
rlon_idx_bnds = rlon_to_idx(cube.coord('grid_longitude').bounds)

# 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
Tos = OceanFixGrid
6 changes: 2 additions & 4 deletions esmvalcore/cmor/_fixes/cmip5/bcc_csm1_1_m.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Fixes for bcc-csm1-1-m."""
from ..common import ClFixHybridPressureCoord
from .bcc_csm1_1 import Tos as BaseTos

from ..common import ClFixHybridPressureCoord, OceanFixGrid

Cl = ClFixHybridPressureCoord


Tos = BaseTos
Tos = OceanFixGrid
58 changes: 3 additions & 55 deletions esmvalcore/cmor/_fixes/cmip6/bcc_csm2_mr.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Fixes for BCC-CSM2-MR model."""
from ..cmip5.bcc_csm1_1 import Tos as BaseTos
from ..common import ClFixHybridPressureCoord

from ..common import ClFixHybridPressureCoord, OceanFixGrid

Cl = ClFixHybridPressureCoord

Expand All @@ -12,57 +10,7 @@
Clw = ClFixHybridPressureCoord


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

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

Tos = OceanFixGrid

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, ))
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
Siconc = OceanFixGrid
6 changes: 2 additions & 4 deletions esmvalcore/cmor/_fixes/cmip6/bcc_esm1.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Fixes for BCC-ESM1 model."""
from ..common import ClFixHybridPressureCoord
from .bcc_csm2_mr import Tos as BaseTos

from ..common import ClFixHybridPressureCoord, OceanFixGrid

Cl = ClFixHybridPressureCoord

Expand All @@ -12,4 +10,4 @@
Clw = ClFixHybridPressureCoord


Tos = BaseTos
Tos = OceanFixGrid
29 changes: 26 additions & 3 deletions esmvalcore/cmor/_fixes/cmip6/fgoals_g3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from ..cmip5.fgoals_g2 import Cl as BaseCl
from ..common import OceanFixGrid


Cl = BaseCl


Expand All @@ -12,7 +11,31 @@
Clw = BaseCl


Tos = OceanFixGrid
class Tos(OceanFixGrid):
"""Fixes for tos."""

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

FGOALS-g3 data contain latitude and longitude data set to >1e30 in some
places.

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

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

"""
cube = self.get_cube_from_list(cubes)
cube.coord('latitude').points[
cube.coord('latitude').points > 1000.0] = 0.0
cube.coord('longitude').points[
cube.coord('longitude').points > 1000.0] = 0.0
return super().fix_metadata(cubes)


Siconc = OceanFixGrid
Siconc = Tos
112 changes: 50 additions & 62 deletions esmvalcore/cmor/_fixes/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Common fixes used for multiple datasets."""
import iris
import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
from scipy.ndimage import map_coordinates

from .fix import Fix
Expand Down Expand Up @@ -108,49 +109,70 @@ def fix_metadata(self, cubes):
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.
def fix_metadata(self, cubes):
"""Fix ``latitude`` and ``longitude`` (metadata and bounds).

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

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

"""
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
cube = self.get_cube_from_list(cubes)

# Get dimensional coordinates. Note:
# - First dimension i -> X-direction (longitude; = dimension 2 in data)
# - Second dimension j -> Y-direction (latitude; = dimension 1 in data)
i_coord = cube.coord(dim_coords=True, dimensions=2)
j_coord = cube.coord(dim_coords=True, dimensions=1)
Comment thread
zklaus marked this conversation as resolved.
Outdated

# Fix metadata of coordinate i
i_coord.var_name = 'i'
i_coord.standard_name = None
i_coord.long_name = 'cell index along first dimension'
i_coord.units = '1'
i_coord.circular = False

# Fix metadata of coordinate j
j_coord.var_name = 'j'
j_coord.standard_name = None
j_coord.long_name = 'cell index along second dimension'
j_coord.units = '1'
Comment thread
schlunma marked this conversation as resolved.

# Guess bounds of coordinates i and j if necessary
if not i_coord.has_bounds():
i_coord.guess_bounds()
if not j_coord.has_bounds():
j_coord.guess_bounds()
Comment thread
zklaus marked this conversation as resolved.
Outdated

# Transform i and j bounds into array indices [0, 1, 2, ...]
i_to_idx = InterpolatedUnivariateSpline(i_coord.points,
np.arange(len(i_coord.points)),
k=1)
j_to_idx = InterpolatedUnivariateSpline(j_coord.points,
np.arange(len(j_coord.points)),
k=1)
i_idx_bnds = i_to_idx(i_coord.bounds)
j_idx_bnds = j_to_idx(j_coord.bounds)
Comment thread
zklaus marked this conversation as resolved.
Outdated

# 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')
for (j, i) in [(0, 0), (0, 1), (1, 1), (1, 0)]:
(j_v, i_v) = np.meshgrid(j_idx_bnds[:, j],
i_idx_bnds[:, i],
indexing='ij')
lat_vertices.append(
map_coordinates(cube.coord('latitude').points,
[rlat_v, rlon_v],
[j_v, i_v],
mode='nearest'))
lon_vertices.append(
map_coordinates(cube.coord('longitude').points,
[rlat_v, rlon_v],
[j_v, i_v],
mode='wrap'))
lat_vertices = np.array(lat_vertices)
lon_vertices = np.array(lon_vertices)
Comment thread
schlunma marked this conversation as resolved.
Outdated
Expand All @@ -160,39 +182,5 @@ def fix_data(self, cube):
# 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
return iris.cube.CubeList([cube])
Loading