diff --git a/mip_convert/mip_convert/requested_variables.py b/mip_convert/mip_convert/requested_variables.py index 31c07e6c4..2d60d9837 100644 --- a/mip_convert/mip_convert/requested_variables.py +++ b/mip_convert/mip_convert/requested_variables.py @@ -128,6 +128,17 @@ def produce_mip_requested_variable( # Process the data by performing the appropriate 'model to MIP mapping', then save the 'MIP output variable' # to an 'output netCDF file'. period = user_config.slicing.get(stream_id, 'year') + + cell_measures_config = ( + user_config.mip_era, + user_config.inpath, + mip_table.id, + variable_name, + frequency, + user_config.global_attributes.get('region', '')) + + saver.cmor.apply_cell_measures(*cell_measures_config, 0) + for time_slice in variable.slices_over(period): time_slice.process() logger.debug('MIP output variable contains: {}'.format(time_slice.info)) diff --git a/mip_convert/mip_convert/save/cmor/cmor_wrapper.py b/mip_convert/mip_convert/save/cmor/cmor_wrapper.py index 56c5a6463..5640f8ded 100644 --- a/mip_convert/mip_convert/save/cmor/cmor_wrapper.py +++ b/mip_convert/mip_convert/save/cmor/cmor_wrapper.py @@ -1,6 +1,8 @@ # (C) British Crown Copyright 2009-2025, Met Office. # Please see LICENSE.md for license details. from collections import OrderedDict +import os +import json import cmor @@ -115,3 +117,38 @@ def zfactor(self, *args, **kwargs): def set_frequency(self, frequency, **kwargs): self._debug_on_args('frequency', [frequency], kwargs) cmor.cmor.set_cur_dataset_attribute('frequency', frequency) + + def apply_cell_measures(self, mip_era, mip_table_dir, realm, variable, frequency, region, variable_id): + """ + Set the cell_measures attribute on a CMOR variable using a lookup in + ``{mip_era}_cell_measures.json`` from the MIP tables directory. Returns + silently if the file does not exist. + + The lookup key has the form ``{realm}.{root_label}.{branding}.{frequency}.{region}`` + (variable name split on ``_``), so entries in the JSON must follow the + convention used for CMIP7. + """ + self._debug_on_args('apply_cell_measures', [mip_era, mip_table_dir, realm, variable, frequency, region, variable_id], {}) + + cell_measures_file = os.path.join(mip_table_dir, f'{mip_era}_cell_measures.json') + + if os.path.exists(cell_measures_file): + with open(cell_measures_file) as fh: + cell_measures = json.load(fh) + if 'cell_measures' not in cell_measures: + self.logger.debug(f'"cell_measures" key not found in {cell_measures_file}') + return + cell_measures = cell_measures['cell_measures'] + + root_label, branding = variable.split('_') + key = f'{realm}.{root_label}.{branding}.{frequency}.{region}' + if key in cell_measures: + retval = cmor.cmor.set_variable_attribute( + variable_id, + 'cell_measures', + 'c', + cell_measures[key]) + if retval != 0: + self.logger.debug('cell_measures assignment failed. Check cmor log file for details') + else: + self.logger.debug(f'Cell_measures file "{cell_measures_file}" not found. Continuing')