Repository: ESMValGroup/ESMValCore

Issue:
Issue with siconca variable in EC-Earth-Consortium models in CMIP6 amip simulation
**Describe the bug**
I assume that there is an issue with **siconca** variable for both models from EC-Earth-Consortium, i.e. **EC-Earth3** and **EC-Earth3-Veg**  in the amip simulation. Sea-ice area should be provided in % and vary from 0 to 100.  In the description of the .nc files from these two models despite it is indicated that units are "%" and comment "Percentage of grid cell covered by sea ice", the values vary from 0 to 1, which stands for the fraction. 

Of course, this affects multi-model mean calculation within ESMValTool.

**Please attach**

Please, see for example: 
/work/ik1017/CMIP6/data/CMIP6/CMIP/EC-Earth-Consortium/EC-Earth3/amip/r1i1p1f1/SImon/siconca/gr/v20200203/
_e.g._: `ncdump -v siconca siconca_SImon_EC-Earth3_amip_r1i1p1f1_gr_197901-197912.nc`

Discussion:
egalytska: @bouweandela could you please have a look at new changes that include your suggestion. 
Btw, Codacy is still complaining =/

Patch:
diff --git a/esmvalcore/cmor/_fixes/cmip6/ec_earth3.py b/esmvalcore/cmor/_fixes/cmip6/ec_earth3.py
new file mode 100644
index 000000000..5e07ee5cd
--- /dev/null
+++ b/esmvalcore/cmor/_fixes/cmip6/ec_earth3.py
@@ -0,0 +1,24 @@
+"""Fixes for EC-Earth3 model."""
+from ..fix import Fix
+
+
+class Siconca(Fix):
+    """Fixes for siconca."""
+
+    def fix_data(self, cube):
+        """Fix data.
+
+        Fixes discrepancy between declared units and real units
+
+        Parameters
+        ----------
+        cube: iris.cube.Cube
+            Input cube which needs to be fixed.
+
+        Returns
+        -------
+        iris.cube.Cube
+
+        """
+        cube.data = cube.core_data() * 100.
+        return cube
diff --git a/esmvalcore/cmor/_fixes/cmip6/ec_earth3_veg.py b/esmvalcore/cmor/_fixes/cmip6/ec_earth3_veg.py
new file mode 100644
index 000000000..d6f1fb9fa
--- /dev/null
+++ b/esmvalcore/cmor/_fixes/cmip6/ec_earth3_veg.py
@@ -0,0 +1,24 @@
+"""Fixes for EC-Earth3-Veg model."""
+from ..fix import Fix
+
+
+class Siconca(Fix):
+    """Fixes for siconca."""
+
+    def fix_data(self, cube):
+        """Fix data.
+
+        Fixes discrepancy between declared units and real units
+
+        Parameters
+        ----------
+        cube: iris.cube.Cube
+            Input cube which needs to be fixed.
+
+        Returns
+        -------
+        iris.cube.Cube
+
+        """
+        cube.data = cube.core_data() * 100.
+        return cube
diff --git a/esmvalcore/cmor/_fixes/shared.py b/esmvalcore/cmor/_fixes/shared.py
index 1f0c6c0e8..da9ed9031 100644
--- a/esmvalcore/cmor/_fixes/shared.py
+++ b/esmvalcore/cmor/_fixes/shared.py
@@ -443,7 +443,7 @@ def round_coordinates(cubes, decimals=5, coord_names=None):
         if not coord_names:
             coords = cube.coords(dim_coords=True)
         else:
-            coords = [cube.coord(name) for name in coord_names]
+            coords = [cube.coord(c) for c in coord_names if cube.coords(c)]
         for coord in coords:
             coord.points = da.round(da.asarray(coord.core_points()), decimals)
             if coord.bounds is not None:
diff --git a/esmvalcore/cmor/tables/custom/CMOR_lweGrace.dat b/esmvalcore/cmor/tables/custom/CMOR_lweGrace.dat
new file mode 100644
index 000000000..fadd4b56e
--- /dev/null
+++ b/esmvalcore/cmor/tables/custom/CMOR_lweGrace.dat
@@ -0,0 +1,22 @@
+SOURCE: CMIP5 (adapted from mrsos)
+!============
+variable_entry:    lweGrace
+!============
+modeling_realm:    land
+!----------------------------------
+! Variable attributes:
+!----------------------------------
+standard_name:
+units:             m
+cell_methods:      time: mean area: mean where land
+cell_measures:     area: areacella
+long_name:         Liquid Water Equivalent Thickness Anomaly
+comment:           liquid water equivalent thickness anomaly
+!----------------------------------
+! Additional variable information:
+!----------------------------------
+dimensions:        longitude latitude time
+out_name:          lweGrace
+type:              real
+!----------------------------------
+!


Test patch:
diff --git a/tests/integration/cmor/_fixes/cmip5/test_fgoals_g2.py b/tests/integration/cmor/_fixes/cmip5/test_fgoals_g2.py
index 36b969a4c..0169bba5d 100644
--- a/tests/integration/cmor/_fixes/cmip5/test_fgoals_g2.py
+++ b/tests/integration/cmor/_fixes/cmip5/test_fgoals_g2.py
@@ -45,6 +45,11 @@ class TestAll(unittest.TestCase):
                          'day since 1-01-01 00:00:00.000000')
         self.assertEqual(time.units.calendar, 'gregorian')
 
+    def test_fix_metadata_dont_fail_if_not_longitude(self):
+        """Test calendar fix."""
+        self.cube.remove_coord('longitude')
+        self.fix.fix_metadata([self.cube])
+
     def test_fix_metadata_dont_fail_if_not_time(self):
         """Test calendar fix."""
         self.cube.remove_coord('time')
diff --git a/tests/integration/cmor/_fixes/cmip6/test_ec_earth3.py b/tests/integration/cmor/_fixes/cmip6/test_ec_earth3.py
new file mode 100644
index 000000000..916b18c93
--- /dev/null
+++ b/tests/integration/cmor/_fixes/cmip6/test_ec_earth3.py
@@ -0,0 +1,30 @@
+"""Tests for MIROC5."""
+import unittest
+
+from cf_units import Unit
+from iris.cube import Cube
+
+from esmvalcore.cmor._fixes.cmip6.ec_earth3 import Siconca
+from esmvalcore.cmor.fix import Fix
+
+
+class TestSiconca(unittest.TestCase):
+    """Test sftof fixes."""
+
+    def setUp(self):
+        """Prepare tests."""
+        self.cube = Cube([1.0], var_name='siconca', units='%')
+        self.fix = Siconca(None)
+
+    def test_get(self):
+        """Test fix get."""
+        self.assertListEqual(Fix.get_fixes('CMIP6',
+                                           'EC-Earth3',
+                                           'SImon', 'siconca'),
+                             [Siconca(None)])
+
+    def test_fix_data(self):
+        """Test data fix."""
+        cube = self.fix.fix_data(self.cube)
+        self.assertEqual(cube.data[0], 100)
+        self.assertEqual(cube.units, Unit('%'))
diff --git a/tests/integration/cmor/_fixes/cmip6/test_ec_earth3_veg.py b/tests/integration/cmor/_fixes/cmip6/test_ec_earth3_veg.py
new file mode 100644
index 000000000..6903f10e0
--- /dev/null
+++ b/tests/integration/cmor/_fixes/cmip6/test_ec_earth3_veg.py
@@ -0,0 +1,30 @@
+"""Tests for MIROC5."""
+import unittest
+
+from cf_units import Unit
+from iris.cube import Cube
+
+from esmvalcore.cmor._fixes.cmip6.ec_earth3_veg import Siconca
+from esmvalcore.cmor.fix import Fix
+
+
+class TestSiconca(unittest.TestCase):
+    """Test sftof fixes."""
+
+    def setUp(self):
+        """Prepare tests."""
+        self.cube = Cube([1.0], var_name='siconca', units='%')
+        self.fix = Siconca(None)
+
+    def test_get(self):
+        """Test fix get."""
+        self.assertListEqual(Fix.get_fixes('CMIP6',
+                                           'EC-Earth3-Veg',
+                                           'SImon', 'siconca'),
+                             [Siconca(None)])
+
+    def test_fix_data(self):
+        """Test data fix."""
+        cube = self.fix.fix_data(self.cube)
+        self.assertEqual(cube.data[0], 100)
+        self.assertEqual(cube.units, Unit('%'))