22
33from __future__ import annotations
44
5- from shutil import copyfile
65from typing import TYPE_CHECKING
76
87import iris
98import iris .coords
9+ import ncdata
10+ import ncdata .netcdf4
1011import numpy as np
11- from netCDF4 import Dataset
1212
1313from esmvalcore .cmor ._fixes .common import SiconcFixScalarCoord
1414from esmvalcore .cmor ._fixes .fix import Fix
1919 add_scalar_typesea_coord ,
2020 fix_ocean_depth_coord ,
2121)
22+ from esmvalcore .iris_helpers import dataset_to_iris
2223
2324if TYPE_CHECKING :
25+ from collections .abc import Sequence
2426 from pathlib import Path
2527
28+ from iris .cube import Cube
29+
2630
2731class Cl (Fix ):
2832 """Fixes for ``cl``."""
2933
30- def _fix_formula_terms (
31- self ,
32- file : str | Path ,
33- output_dir : str | Path ,
34- add_unique_suffix : bool = False ,
35- ) -> Path :
34+ @staticmethod
35+ def _fix_formula_terms (dataset : ncdata .NcData ) -> None :
3636 """Fix ``formula_terms`` attribute."""
37- new_path = self .get_fixed_filepath (
38- output_dir ,
39- file ,
40- add_unique_suffix = add_unique_suffix ,
37+ lev = dataset .variables ["lev" ]
38+ lev .set_attrval ("formula_terms" , "p0: p0 a: a b: b ps: ps" )
39+ lev .set_attrval (
40+ "standard_name" ,
41+ "atmosphere_hybrid_sigma_pressure_coordinate" ,
4142 )
42- copyfile (file , new_path )
43- with Dataset (new_path , mode = "a" ) as dataset :
44- dataset .variables ["lev" ].formula_terms = "p0: p0 a: a b: b ps: ps"
45- dataset .variables [
46- "lev"
47- ].standard_name = "atmosphere_hybrid_sigma_pressure_coordinate"
48- return new_path
43+ lev .set_attrval ("units" , "1" )
44+ dataset .variables ["lev_bnds" ].attributes .pop ("units" )
4945
5046 def fix_file (
5147 self ,
52- file : str | Path ,
53- output_dir : str | Path ,
54- add_unique_suffix : bool = False ,
55- ) -> Path :
48+ file : Path ,
49+ output_dir : Path , # noqa: ARG002
50+ add_unique_suffix : bool = False , # noqa: ARG002
51+ ) -> Path | Sequence [ Cube ] :
5652 """Fix hybrid pressure coordinate.
5753
5854 Adds missing ``formula_terms`` attribute to file.
@@ -79,45 +75,38 @@ def fix_file(
7975 Path to the fixed file.
8076
8177 """
82- new_path = self . _fix_formula_terms (
78+ dataset = ncdata . netcdf4 . from_nc4 (
8379 file ,
84- output_dir ,
85- add_unique_suffix = add_unique_suffix ,
80+ # Use iris-style chunks to avoid mismatching chunks between data
81+ # and derived coordinates, as the latter are automatically rechunked
82+ # by iris.
83+ dim_chunks = {
84+ "time" : "auto" ,
85+ "lev" : None ,
86+ "lat" : None ,
87+ "lon" : None ,
88+ "nbnd" : None ,
89+ },
8690 )
87- with Dataset (new_path , mode = "a" ) as dataset :
88- dataset .variables ["a_bnds" ][:] = dataset .variables ["a_bnds" ][
89- ::- 1 ,
90- :,
91- ]
92- dataset .variables ["b_bnds" ][:] = dataset .variables ["b_bnds" ][
93- ::- 1 ,
94- :,
95- ]
96- return new_path
97-
98- def fix_metadata (self , cubes ):
99- """Fix ``atmosphere_hybrid_sigma_pressure_coordinate``.
100-
101- See discussion in #882 for more details on that.
102-
103- Parameters
104- ----------
105- cubes : iris.cube.CubeList
106- Input cubes.
107-
108- Returns
109- -------
110- iris.cube.CubeList
111-
112- """
113- cube = self .get_cube_from_list (cubes )
114- lev_coord = cube .coord (var_name = "lev" )
115- a_coord = cube .coord (var_name = "a" )
116- b_coord = cube .coord (var_name = "b" )
117- lev_coord .points = a_coord .core_points () + b_coord .core_points ()
118- lev_coord .bounds = a_coord .core_bounds () + b_coord .core_bounds ()
119- lev_coord .units = "1"
120- return cubes
91+ self ._fix_formula_terms (dataset )
92+
93+ # Correct order of bounds data
94+ a_bnds = dataset .variables ["a_bnds" ]
95+ a_bnds .data = a_bnds .data [::- 1 , :]
96+ b_bnds = dataset .variables ["b_bnds" ]
97+ b_bnds .data = b_bnds .data [::- 1 , :]
98+
99+ # Correct lev and lev_bnds data
100+ lev = dataset .variables ["lev" ]
101+ lev .data = dataset .variables ["a" ].data + dataset .variables ["b" ].data
102+ lev_bnds = dataset .variables ["lev_bnds" ]
103+ lev_bnds .data = (
104+ dataset .variables ["a_bnds" ].data + dataset .variables ["b_bnds" ].data
105+ )
106+ # Remove 'title' attribute that duplicates long name
107+ for var_name in dataset .variables :
108+ dataset .variables [var_name ].attributes .pop ("title" , None )
109+ return [self .get_cube_from_list (dataset_to_iris (dataset , file ))]
121110
122111
123112Cli = Cl
0 commit comments