From 5f772f8356bed50a4b600d69c237ffd43e911cdf Mon Sep 17 00:00:00 2001 From: Axel Lauer Date: Fri, 4 Feb 2022 14:56:18 +0100 Subject: [PATCH 1/5] fixes for clisccp and airs --- esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py | 35 +++++++++++++++++++ .../cmor/tables/custom/CMOR_clisccp.dat | 4 +-- .../cmor/tables/custom/CMOR_coordinates.dat | 17 ++++++++- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py diff --git a/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py new file mode 100644 index 0000000000..99537e34f9 --- /dev/null +++ b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py @@ -0,0 +1,35 @@ + +"""Fixes for obs4mips dataset AIRS-2-1.""" +import iris +from iris.cube import CubeList +from cf_units import Unit + +from ..fix import Fix + + +class AllVars(Fix): + """Common fixes to all vars.""" + + def fix_metadata(self, cubes): + """ + Fix metadata. + + Change unit of coordinate plev from hPa to Pa + + Parameters + ---------- + cube: iris.cube.CubeList + + Returns + ------- + iris.cube.Cube + + """ + for cube in cubes: + try: + plev = cube.coord('air_pressure') + except iris.exceptions.CoordinateNotFoundError: + continue + else: + plev.units = Unit('Pa') + return cubes diff --git a/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat b/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat index b86353b3ed..be184c37a6 100644 --- a/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat +++ b/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat @@ -14,8 +14,8 @@ long_name: ISCCP Cloud Area Fraction !---------------------------------- ! Additional variable information: !---------------------------------- -dimensions: longitude latitude plevs tau time +dimensions: longitude latitude plev7 tau time out_name: clisccp type: real !---------------------------------- -! \ No newline at end of file +! diff --git a/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat b/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat index 490ddab6f5..0a12bcf725 100644 --- a/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat +++ b/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat @@ -86,13 +86,28 @@ must_have_bounds: yes !---------------------------------- ! +!============ +axis_entry: plev7 +!============ +axis: Z +long_name: pressure +must_have_bounds: yes +out_name: plev7 +positive: down +requested: 90000. 74000. 62000. 50000. 37500. 24500. 9000. +requested_bounds: 100000. 80000. 80000. 68000. 68000. 56000. 56000. 44000. 44000. 31000. 31000. 18000. 18000. 0. +standard_name: air_pressure +stored_direction: decreasing +units: Pa + + !============ axis_entry: tau !============ !---------------------------------- ! Axis attributes: !---------------------------------- -standard_name: atmosphere_optical_thickness_due_to_cloud +!standard_name: atmosphere_optical_thickness_due_to_cloud units: 1 long_name: cloud optical thickness !---------------------------------- From 5a4b07e926c2ba3223b40411e39c46eeea65f0d9 Mon Sep 17 00:00:00 2001 From: Manuel Schlund <32543114+schlunma@users.noreply.github.com> Date: Mon, 7 Feb 2022 10:58:31 +0100 Subject: [PATCH 2/5] Update esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py --- esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py | 1 - 1 file changed, 1 deletion(-) diff --git a/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py index 99537e34f9..c71afbe2db 100644 --- a/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py +++ b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py @@ -1,4 +1,3 @@ - """Fixes for obs4mips dataset AIRS-2-1.""" import iris from iris.cube import CubeList From 74164ce169b9a8a3b92620fa3b05406f623d4a0f Mon Sep 17 00:00:00 2001 From: Manuel Schlund Date: Mon, 7 Feb 2022 11:28:22 +0100 Subject: [PATCH 3/5] Added tests for fix --- .github/workflows/install-from-pypi.yml | 4 +- esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py | 7 +- .../cmor/_fixes/obs4mips/test_airs_2_1.py | 77 +++++++++++++++++++ 3 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 tests/integration/cmor/_fixes/obs4mips/test_airs_2_1.py diff --git a/.github/workflows/install-from-pypi.yml b/.github/workflows/install-from-pypi.yml index c758b93299..c60675c013 100644 --- a/.github/workflows/install-from-pypi.yml +++ b/.github/workflows/install-from-pypi.yml @@ -15,7 +15,7 @@ name: Install from PyPi # runs on a push on main and at the end of every day on: - # triggering on push without branch name will run tests everytime + # triggering on push without branch name will run tests every time # there is a push on any branch # turn it on only if needed push: @@ -36,7 +36,7 @@ jobs: matrix: python-version: ["3.7", "3.8", "3.9", "3.10"] # fail-fast set to False allows all other tests - # in the worflow to run regardless of any fail + # in the workflow to run regardless of any fail fail-fast: false name: Linux Python ${{ matrix.python-version }} steps: diff --git a/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py index c71afbe2db..07a6ebfcb7 100644 --- a/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py +++ b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py @@ -1,7 +1,7 @@ -"""Fixes for obs4mips dataset AIRS-2-1.""" +"""Fixes for obs4MIPs dataset AIRS-2-1.""" import iris -from iris.cube import CubeList from cf_units import Unit +from iris.cube import CubeList from ..fix import Fix @@ -30,5 +30,6 @@ def fix_metadata(self, cubes): except iris.exceptions.CoordinateNotFoundError: continue else: - plev.units = Unit('Pa') + if plev.points[0] > 10000.0: + plev.units = Unit('Pa') return cubes diff --git a/tests/integration/cmor/_fixes/obs4mips/test_airs_2_1.py b/tests/integration/cmor/_fixes/obs4mips/test_airs_2_1.py new file mode 100644 index 0000000000..4ac2ce7f26 --- /dev/null +++ b/tests/integration/cmor/_fixes/obs4mips/test_airs_2_1.py @@ -0,0 +1,77 @@ +"""Test AIRS-2-1 fixes.""" +import numpy as np +from iris.coords import DimCoord +from iris.cube import Cube, CubeList + +from esmvalcore.cmor._fixes.obs4mips.airs_2_1 import AllVars +from esmvalcore.cmor.fix import Fix + + +def get_air_pressure_coord(points, units): + """Get ``air_pressure`` coordinate.""" + return DimCoord(points, var_name='plev', standard_name='air_pressure', + long_name='pressure', units=units) + + +def test_get_allvars_fix(): + """Test getting of fix.""" + fix = Fix.get_fixes('obs4MIPs', 'AIRS-2-1', 'Amon', 'cl') + assert fix == [AllVars(None)] + + +def test_allvars_fix_no_air_pressure(): + """Test fix for all variables.""" + cubes = CubeList([Cube(0.0, var_name='cl')]) + fix = AllVars(None) + out_cubes = fix.fix_metadata(cubes.copy()) + + assert len(out_cubes) == 1 + assert out_cubes[0] == cubes[0] + + +def test_allvars_fix_correct_air_pressure_pa(): + """Test fix for all variables.""" + air_pressure_coord = get_air_pressure_coord([100000.0, 80000.0], 'Pa') + cube = Cube([0.0, 1.0], var_name='cl', + dim_coords_and_dims=[(air_pressure_coord, 0)]) + cubes = CubeList([cube]) + fix = AllVars(None) + out_cubes = fix.fix_metadata(cubes.copy()) + + assert len(out_cubes) == 1 + assert out_cubes[0] == cubes[0] + assert out_cubes[0].coord('air_pressure').units == 'Pa' + np.testing.assert_allclose(out_cubes[0].coord('air_pressure').points, + [100000.0, 80000.0]) + + +def test_allvars_fix_correct_air_pressure_hpa(): + """Test fix for all variables.""" + air_pressure_coord = get_air_pressure_coord([1000.0, 800.0], 'hPa') + cube = Cube([0.0, 1.0], var_name='cl', + dim_coords_and_dims=[(air_pressure_coord, 0)]) + cubes = CubeList([cube]) + fix = AllVars(None) + out_cubes = fix.fix_metadata(cubes.copy()) + + assert len(out_cubes) == 1 + assert out_cubes[0] == cubes[0] + assert out_cubes[0].coord('air_pressure').units == 'hPa' + np.testing.assert_allclose(out_cubes[0].coord('air_pressure').points, + [1000.0, 800.0]) + + +def test_allvars_fix_incorrect_air_pressure(): + """Test fix for all variables.""" + air_pressure_coord = get_air_pressure_coord([100000.0, 80000.0], 'hPa') + cube = Cube([0.0, 1.0], var_name='cl', + dim_coords_and_dims=[(air_pressure_coord, 0)]) + cubes = CubeList([cube]) + fix = AllVars(None) + out_cubes = fix.fix_metadata(cubes.copy()) + + assert len(out_cubes) == 1 + assert out_cubes[0] != cubes[0] + assert out_cubes[0].coord('air_pressure').units == 'Pa' + np.testing.assert_allclose(out_cubes[0].coord('air_pressure').points, + [100000.0, 80000.0]) From 7d1350e893b3ffd6db392c227e64e07f25ca9a3c Mon Sep 17 00:00:00 2001 From: Manuel Schlund Date: Mon, 7 Feb 2022 11:35:30 +0100 Subject: [PATCH 4/5] Fixed codacy issues --- esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py index 07a6ebfcb7..93ca03eaa6 100644 --- a/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py +++ b/esmvalcore/cmor/_fixes/obs4mips/airs_2_1.py @@ -1,7 +1,5 @@ """Fixes for obs4MIPs dataset AIRS-2-1.""" -import iris -from cf_units import Unit -from iris.cube import CubeList +from iris.exceptions import CoordinateNotFoundError from ..fix import Fix @@ -13,23 +11,25 @@ def fix_metadata(self, cubes): """ Fix metadata. - Change unit of coordinate plev from hPa to Pa + Change unit of coordinate plev from hPa to Pa. Parameters ---------- - cube: iris.cube.CubeList + cubes: iris.cube.CubeList + Input cubes. Returns ------- - iris.cube.Cube + iris.cube.CubeList + Fixed cubes. """ for cube in cubes: try: plev = cube.coord('air_pressure') - except iris.exceptions.CoordinateNotFoundError: + except CoordinateNotFoundError: continue else: if plev.points[0] > 10000.0: - plev.units = Unit('Pa') + plev.units = 'Pa' return cubes From 6615883948e22c908b6f0264f74dc26b3584718f Mon Sep 17 00:00:00 2001 From: Axel Lauer Date: Tue, 8 Feb 2022 10:28:36 +0100 Subject: [PATCH 5/5] reverted changes for clisccp --- esmvalcore/cmor/tables/custom/CMOR_clisccp.dat | 4 ++-- .../cmor/tables/custom/CMOR_coordinates.dat | 17 +---------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat b/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat index be184c37a6..b86353b3ed 100644 --- a/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat +++ b/esmvalcore/cmor/tables/custom/CMOR_clisccp.dat @@ -14,8 +14,8 @@ long_name: ISCCP Cloud Area Fraction !---------------------------------- ! Additional variable information: !---------------------------------- -dimensions: longitude latitude plev7 tau time +dimensions: longitude latitude plevs tau time out_name: clisccp type: real !---------------------------------- -! +! \ No newline at end of file diff --git a/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat b/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat index 0a12bcf725..490ddab6f5 100644 --- a/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat +++ b/esmvalcore/cmor/tables/custom/CMOR_coordinates.dat @@ -86,28 +86,13 @@ must_have_bounds: yes !---------------------------------- ! -!============ -axis_entry: plev7 -!============ -axis: Z -long_name: pressure -must_have_bounds: yes -out_name: plev7 -positive: down -requested: 90000. 74000. 62000. 50000. 37500. 24500. 9000. -requested_bounds: 100000. 80000. 80000. 68000. 68000. 56000. 56000. 44000. 44000. 31000. 31000. 18000. 18000. 0. -standard_name: air_pressure -stored_direction: decreasing -units: Pa - - !============ axis_entry: tau !============ !---------------------------------- ! Axis attributes: !---------------------------------- -!standard_name: atmosphere_optical_thickness_due_to_cloud +standard_name: atmosphere_optical_thickness_due_to_cloud units: 1 long_name: cloud optical thickness !----------------------------------