1-
21"""Thin CMOR wrapper used by cmip7_prep.
32
43This module centralizes CMOR session setup and writing so that the rest of the
54pipeline can stay xarray-first. It supports either a dataset JSON file (preferred)
65or directly injected global attributes, and creates axes based on the coordinates
76present in the provided dataset.
87"""
8+
99from __future__ import annotations
1010
1111from contextlib import AbstractContextManager
@@ -88,10 +88,14 @@ def _define_axes(self, ds: xr.Dataset, vdef: Any) -> list[int]:
8888 cal = time .attrs .get ("calendar" , "standard" )
8989 if np .issubdtype (time .dtype , np .datetime64 ):
9090 # convert to numeric time using CF units if needed
91- tvals = xr .conventions .times .encode_cf_datetime (time .values , t_units , calendar = cal )
91+ tvals = xr .conventions .times .encode_cf_datetime (
92+ time .values , t_units , calendar = cal
93+ )
9294 else :
9395 tvals = time .values
94- axes .append (cmor .axis (table_entry = "time" , units = str (t_units ), coord_vals = tvals ))
96+ axes .append (
97+ cmor .axis (table_entry = "time" , units = str (t_units ), coord_vals = tvals )
98+ )
9599
96100 # Vertical axis (pressure or model levels)
97101 levels_info = getattr (vdef , "levels" , None )
@@ -121,7 +125,9 @@ def _define_axes(self, ds: xr.Dataset, vdef: Any) -> list[int]:
121125 table_entry = "alev"
122126 if isinstance (levels_info , dict ):
123127 table_entry = levels_info .get ("axis_entry" , table_entry )
124- axes .append (cmor .axis (table_entry = table_entry , units = "1" , coord_vals = lev .values ))
128+ axes .append (
129+ cmor .axis (table_entry = table_entry , units = "1" , coord_vals = lev .values )
130+ )
125131
126132 # Latitude / Longitude
127133 if "lat" in ds .coords and "lon" in ds .coords :
@@ -152,7 +158,9 @@ def _define_axes(self, ds: xr.Dataset, vdef: Any) -> list[int]:
152158 # public API
153159 # -------------------------
154160
155- def write_variable (self , ds : xr .Dataset , varname : str , vdef : Any , outdir : Path ) -> None :
161+ def write_variable (
162+ self , ds : xr .Dataset , varname : str , vdef : Any , outdir : Path
163+ ) -> None :
156164 """Write one variable from `ds` to a CMOR-compliant NetCDF file.
157165
158166 Parameters
@@ -162,8 +170,10 @@ def write_variable(self, ds: xr.Dataset, varname: str, vdef: Any, outdir: Path)
162170 varname : str
163171 Name of the variable in `ds` to CMORize.
164172 vdef : Any
165- An object with fields: ``name``, ``realm``, optional ``units``, ``positive``, and optional
166- ``levels`` dict (see :meth:`_define_axes`). This is typically a light-weight holder.
173+ An object with fields: ``name``, ``realm``,
174+ optional ``units``, ``positive``, and optional
175+ ``levels`` dict (see :meth:`_define_axes`).
176+ This is typically a light-weight holder.
167177 outdir : Path
168178 Output directory for the CMORized NetCDF file.
169179 """
@@ -182,8 +192,12 @@ def write_variable(self, ds: xr.Dataset, varname: str, vdef: Any, outdir: Path)
182192
183193 axes_ids = self ._define_axes (ds , vdef )
184194 units = getattr (vdef , "units" , "" )
185- var_id = cmor .variable (getattr (vdef , "name" , varname ), units , axes_ids ,
186- positive = getattr (vdef , "positive" , None ))
195+ var_id = cmor .variable (
196+ getattr (vdef , "name" , varname ),
197+ units ,
198+ axes_ids ,
199+ positive = getattr (vdef , "positive" , None ),
200+ )
187201
188202 # Optional variable attributes (e.g., cell_methods)
189203 if getattr (vdef , "cell_methods" , None ):
0 commit comments