diff --git a/lib/iris/fileformats/cf.py b/lib/iris/fileformats/cf.py index 8393965453..37d6197aa7 100644 --- a/lib/iris/fileformats/cf.py +++ b/lib/iris/fileformats/cf.py @@ -16,7 +16,6 @@ from abc import ABCMeta, abstractmethod from collections.abc import Iterable, MutableMapping -import contextlib import os import re from typing import ClassVar, Optional @@ -1425,14 +1424,18 @@ def _translate(self, variables): # cf_var = CFFormulaTermsVariable (loops through everything that appears in formula terms) for cf_var in formula_terms.values(): - # eg. eta:'a' | cf_root = eta and cf_term = a. cf_var.cf_terms_by_root = {'eta': 'a'} (looking at all appearances in formula terms) + # Example of a formula term: + # Suppose in the file eta:formula_terms contains "a: var_A" + # cf_var = var_A, cf_root = eta and cf_term = 'a'. cf_var.cf_terms_by_root = {eta: 'a'} for cf_root, cf_term in cf_var.cf_terms_by_root.items(): if iris.FUTURE.derived_bounds: # For the "newstyle" derived-bounds implementation, find vars which appear in derived bounds terms # and turn them into bounds vars (though they don't appear in a "bounds" attribute) + + # Adds each root only once all_roots.add(cf_root) - # cf_root_coord = CFCoordinateVariable of the coordinate relating to the root + # cf_root_coord = CFCoordinateVariable or CFAuxiliaryCoordinateVariable of the coordinate relating to the root cf_root_coord = self.cf_group.coordinates.get(cf_root) if cf_root_coord is None: cf_root_coord = self.cf_group.auxiliary_coordinates.get(cf_root) @@ -1443,10 +1446,10 @@ def _translate(self, variables): if root_bounds_name in self.cf_group: root_bounds_var = self.cf_group.get(root_bounds_name) if not hasattr(root_bounds_var, "formula_terms"): - # this is an invalid root bounds, according to CF + # this is an invalid root bounds, according to CF, and therefore should be promoted into a cube root_bounds_var._to_be_promoted = True else: - # Found a valid *root* bounds variable : search for a corresponding *term* bounds variable + # Found a valid *root* bounds variable : search for a corresponding *term* bounds variable, term_bounds_vars = [ # loop through all formula terms and add them if they have a cf_term_by_root # where (bounds of cf_root): cf_term (same as before) @@ -1456,8 +1459,8 @@ def _translate(self, variables): ] if len(term_bounds_vars) == 1: (term_bounds_var,) = term_bounds_vars + # N.B. bounds==main-var is valid CF for *no* bounds if term_bounds_var != cf_var: - # N.B. bounds==main-var is valid CF for *no* bounds cf_var.bounds = term_bounds_var.cf_name new_var = CFBoundaryVariable( term_bounds_var.cf_name, term_bounds_var.cf_data @@ -1467,12 +1470,13 @@ def _translate(self, variables): self.cf_group[term_bounds_var.cf_name] = new_var if cf_root not in self.cf_group.bounds: - # TODO: explain this section ? + # This records all formula terms in the main cf_group that were previously only stored in the formula_terms dictionary. cf_name = cf_var.cf_name if cf_name not in self.cf_group: + # If the formula term variable is not already in the group, add it as a coordinate. new_var = CFAuxiliaryCoordinateVariable(cf_name, cf_var.cf_data) if iris.FUTURE.derived_bounds and hasattr(cf_var, "bounds"): - # Implement "new-style" derived bounds link + # Copy "old-style" derived bounds link new_var.bounds = cf_var.bounds self.cf_group[cf_name] = new_var @@ -1490,7 +1494,8 @@ def _translate(self, variables): root_bounds_var is not None and "formula_terms" not in root_bounds_var.ncattrs() ): - # This means it is *not* a valid bounds var, according to CF + # This means it is *not* a valid bounds var, according to CF, and so therefore we are + # invalidating the bounds. root_var.bounds = None # Determine the CF data variables. @@ -1565,7 +1570,7 @@ def _span_check( _span_check(cf_name) if iris.FUTURE.derived_bounds: - # TODO: explain this section + # Include bounds of every variable, within cf_group attached to the variable. if hasattr(cf_variable, "bounds"): if cf_variable.bounds not in cf_group: bounds_var = self.cf_group.get(cf_variable.bounds)