def _check_height(self, blev, stash, expect_normal=True, expect_fixed_height=None, dim=None): lbvc = 1 lbcode = _lbcode(0) # effectively unused in this case lblev, bhlev, bhrlev, brsvd1, brsvd2, brlev = \ None, None, None, None, None, None coords_and_dims, factories = _convert_vertical_coords(lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_normal: expect_result = [(DimCoord(blev, standard_name='height', units='m', attributes={'positive': 'up'}), dim)] elif expect_fixed_height: expect_result = [(DimCoord(expect_fixed_height, standard_name='height', units='m', attributes={'positive': 'up'}), None)] else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check(self, lblev=37.0, blev=9596.3, brlev=9500.0, brsvd1=9800.0, bhlev=0.35, bhrlev=0.31, brsvd2=0.39, dim=None): lbvc = 65 lbcode = _lbcode(0) # unused stash = STASH(1, 1, 1) # unused coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) expect_coords_and_dims = [ (DimCoord(lblev, standard_name='model_level_number', attributes={'positive': 'up'}), dim)] brlev = np.atleast_1d(brlev) brsvd1 = np.atleast_1d(brsvd1) expect_coords_and_dims.append( (DimCoord(blev, long_name='level_height', units='m', bounds=np.vstack((brlev, brsvd1)).T, attributes={'positive': 'up'}), dim)) bhrlev = np.atleast_1d(bhrlev) brsvd2 = np.atleast_1d(brsvd2) expect_coords_and_dims.append( (AuxCoord(bhlev, long_name='sigma', bounds=np.vstack((bhrlev, brsvd2)).T), dim)) expect_factories = [(HybridHeightFactory, [{'long_name': 'level_height'}, {'long_name': 'sigma'}, Reference('orography')])] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_coords_and_dims) self.assertEqual(factories, expect_factories)
def _check_potm(self, lbcode, blev=130.6, expect_match=True, dim=None): lbvc = 19 stash = STASH(1, 1, 1) lblev, bhlev, bhrlev, brsvd1, brsvd2, brlev = \ None, None, None, None, None, None coords_and_dims, factories = _convert_vertical_coords(lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_match: expect_result = [ (DimCoord(blev, standard_name='air_potential_temperature', units='K', attributes={'positive': 'up'}), dim) ] else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_soil_depth(self, lbcode, blev=0.05, brsvd1=0, brlev=0.1, expect_match=True, dim=None): lbvc = 6 stash = STASH(1, 1, 1) lblev, bhlev, bhrlev, brsvd2 = None, None, None, None coords_and_dims, factories = _convert_vertical_coords(lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) expect_result = [] if expect_match: coord = DimCoord(blev, standard_name='depth', bounds=np.vstack((brsvd1, brlev)).T, units='m', attributes={'positive': 'down'}) expect_result = [(coord, dim)] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_soil_level(self, lbcode, lblev=12.3, expect_match=True, dim=None): lbvc = 6 stash = STASH(1, 1, 1) brsvd1, brlev = 0, 0 if hasattr(lblev, '__iter__'): brsvd1 = [0] * len(lblev) brlev = [0] * len(lblev) blev, bhlev, bhrlev, brsvd2 = None, None, None, None coords_and_dims, factories = _convert_vertical_coords(lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) expect_result = [] if expect_match: coord = DimCoord(lblev, long_name='soil_model_level_number', attributes={'positive': 'down'}) expect_result = [(coord, dim)] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_depth(self, lbcode, lblev=23.0, blev=123.4, brlev=0.0, brsvd1=0.0, expect_bounds=True, expect_match=True, expect_mixed=False, dim=None): lbvc = 2 stash = STASH(1, 1, 1) bhlev, bhrlev, brsvd2 = None, None, None coords_and_dims, factories = _convert_vertical_coords(lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_match: expect_result = [(DimCoord(lblev, standard_name='model_level_number', attributes={'positive': 'down'}), dim)] if expect_bounds: brsvd1 = np.atleast_1d(brsvd1) brlev = np.atleast_1d(brlev) if expect_mixed: lower = np.where(brsvd1 == brlev, blev, brsvd1) upper = np.where(brsvd1 == brlev, blev, brlev) else: lower, upper = brsvd1, brlev bounds = np.vstack((lower, upper)).T expect_result.append((DimCoord(blev, standard_name='depth', units='m', bounds=bounds, attributes={'positive': 'down'}), dim)) else: expect_result.append((DimCoord(blev, standard_name='depth', units='m', attributes={'positive': 'down'}), dim)) else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def test_unknown_lbvc(self): lbvc = 999 blev, lblev, bhlev, bhrlev, brsvd1, brsvd2, brlev = \ None, None, None, None, None, None, None lbcode = _lbcode(0) # unused stash = STASH(1, 1, 1) # unused coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev) self.assertEqual(coords_and_dims, []) self.assertEqual(factories, [])
def _check(self, lblev=37.0, bhlev=850.1, bhrlev=810.0, brsvd2=875.0, blev=0.15, brlev=0.11, brsvd1=0.19, expect_match=True, dim=None): lbvc = 9 lbcode = _lbcode(0) # unused stash = STASH(1, 1, 1) # unused coords_and_dims, factories = _convert_vertical_coords(lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) expect_coords_and_dims = [(DimCoord(lblev, standard_name='model_level_number', attributes={'positive': 'up'}), dim)] bhrlev = np.atleast_1d(bhrlev) brsvd2 = np.atleast_1d(brsvd2) expect_coords_and_dims.append((DimCoord(bhlev, long_name='level_pressure', units='Pa', bounds=np.vstack( (bhrlev, brsvd2)).T), dim)) brlev = np.atleast_1d(brlev) brsvd1 = np.atleast_1d(brsvd1) expect_coords_and_dims.append((AuxCoord(blev, long_name='sigma', bounds=np.vstack( (brlev, brsvd1)).T), dim)) expect_factories = [(HybridPressureFactory, [{ 'long_name': 'level_pressure' }, { 'long_name': 'sigma' }, Reference('surface_air_pressure')])] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_coords_and_dims) self.assertEqual(factories, expect_factories)
def _check_pressure(self, lbcode, blev=250.3, expect_match=True, dim=None): lbvc = 8 stash = STASH(1, 1, 1) lblev, bhlev, bhrlev, brsvd1, brsvd2, brlev = \ None, None, None, None, None, None coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_match: expect_result = [ (DimCoord(blev, long_name='pressure', units='hPa'), dim)] else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_potm(self, lbcode, blev=130.6, expect_match=True, dim=None): lbvc = 19 stash = STASH(1, 1, 1) lblev, bhlev, bhrlev, brsvd1, brsvd2, brlev = \ None, None, None, None, None, None coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_match: expect_result = [ (DimCoord(blev, standard_name='air_potential_temperature', units='K', attributes={'positive': 'up'}), dim)] else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_soil_depth(self, lbcode, blev=0.05, brsvd1=0, brlev=0.1, expect_match=True, dim=None): lbvc = 6 stash = STASH(1, 1, 1) lblev, bhlev, bhrlev, brsvd2 = None, None, None, None coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) expect_result = [] if expect_match: coord = DimCoord(blev, standard_name='depth', bounds=np.vstack((brsvd1, brlev)).T, units='m', attributes={'positive': 'down'}) expect_result = [(coord, dim)] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_soil_level(self, lbcode, lblev=12.3, expect_match=True, dim=None): lbvc = 6 stash = STASH(1, 1, 1) blev, bhlev, bhrlev, brsvd1, brsvd2, brlev = \ None, None, None, None, None, None coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_match: expect_result = [ (DimCoord(lblev, long_name='soil_model_level_number', attributes={'positive': 'down'}), dim)] else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_depth(self, lbcode, lblev=23.0, blev=123.4, brlev=0.0, brsvd1=0.0, expect_bounds=True, expect_match=True, expect_mixed=False, dim=None): lbvc = 2 stash = STASH(1, 1, 1) bhlev, bhrlev, brsvd2 = None, None, None coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_match: expect_result = [ (DimCoord(lblev, standard_name='model_level_number', attributes={'positive': 'down'}), dim)] if expect_bounds: brsvd1 = np.atleast_1d(brsvd1) brlev = np.atleast_1d(brlev) if expect_mixed: lower = np.where(brsvd1 == brlev, blev, brsvd1) upper = np.where(brsvd1 == brlev, blev, brlev) else: lower, upper = brsvd1, brlev bounds = np.vstack((lower, upper)).T expect_result.append( (DimCoord(blev, standard_name='depth', units='m', bounds=bounds, attributes={'positive': 'down'}), dim)) else: expect_result.append( (DimCoord(blev, standard_name='depth', units='m', attributes={'positive': 'down'}), dim)) else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check_height(self, blev, stash, expect_normal=True, expect_fixed_height=None, dim=None): lbvc = 1 lbcode = _lbcode(0) # effectively unused in this case lblev, bhlev, bhrlev, brsvd1, brsvd2, brlev = \ None, None, None, None, None, None coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) if expect_normal: expect_result = [ (DimCoord(blev, standard_name='height', units='m', attributes={'positive': 'up'}), dim)] elif expect_fixed_height: expect_result = [ (DimCoord(expect_fixed_height, standard_name='height', units='m', attributes={'positive': 'up'}), None)] else: expect_result = [] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_result) self.assertEqual(factories, [])
def _check(self, lblev=37.0, bhlev=850.1, bhrlev=810.0, brsvd2=875.0, blev=0.15, brlev=0.11, brsvd1=0.19, expect_match=True, dim=None): lbvc = 9 lbcode = _lbcode(0) # unused stash = STASH(1, 1, 1) # unused coords_and_dims, factories = _convert_vertical_coords( lbcode=lbcode, lbvc=lbvc, blev=blev, lblev=lblev, stash=stash, bhlev=bhlev, bhrlev=bhrlev, brsvd1=brsvd1, brsvd2=brsvd2, brlev=brlev, dim=dim) expect_coords_and_dims = [ (DimCoord(lblev, standard_name='model_level_number', attributes={'positive': 'up'}), dim)] bhrlev = np.atleast_1d(bhrlev) brsvd2 = np.atleast_1d(brsvd2) expect_coords_and_dims.append( (DimCoord(bhlev, long_name='level_pressure', units='Pa', bounds=np.vstack((bhrlev, brsvd2)).T), dim)) brlev = np.atleast_1d(brlev) brsvd1 = np.atleast_1d(brsvd1) expect_coords_and_dims.append( (AuxCoord(blev, long_name='sigma', bounds=np.vstack((brlev, brsvd1)).T), dim)) expect_factories = [(HybridPressureFactory, [{'long_name': 'level_pressure'}, {'long_name': 'sigma'}, Reference('surface_air_pressure')])] self.assertCoordsAndDimsListsMatch(coords_and_dims, expect_coords_and_dims) self.assertEqual(factories, expect_factories)
def _convert_collation(collation): """ Converts a FieldCollation into the corresponding items of Cube metadata. Args: * collation: A FieldCollation object. Returns: A :class:`iris.fileformats.rules.ConversionMetadata` object. .. note: This is the 'loader.converter', in the control structure passed to the generic rules code, :meth:`iris.fileformats.rules.load_cubes`. """ from iris.fileformats.rules import ConversionMetadata from iris.fileformats.pp_rules import (_convert_time_coords, _convert_vertical_coords, _convert_scalar_realization_coords, _convert_scalar_pseudo_level_coords, _all_other_rules) # For all the scalar conversions, all fields in the collation will # give the same result, so the choice is arbitrary. field = collation.fields[0] # Call "all other" rules. (references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field) # Adjust any dimension bindings to account for the extra leading # dimensions added by the collation. if collation.vector_dims_shape: def _adjust_dims(coords_and_dims, n_dims): def adjust(dims): if dims is not None: dims += n_dims return dims return [(coord, adjust(dims)) for coord, dims in coords_and_dims] n_collation_dims = len(collation.vector_dims_shape) dim_coords_and_dims = _adjust_dims(dim_coords_and_dims, n_collation_dims) aux_coords_and_dims = _adjust_dims(aux_coords_and_dims, n_collation_dims) # Dimensions to which we've already assigned dimension coordinates. dim_coord_dims = set() # Helper call to choose which coords are dimensions and which auxiliary. def _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims): def key_func(item): return _HINTS.get(item[0].name(), len(_HINTS)) # Target the first DimCoord for a dimension at dim_coords, # and target everything else at aux_coords. for coord, dims in sorted(coords_and_dims, key=key_func): if (isinstance(coord, DimCoord) and dims is not None and len(dims) == 1 and dims[0] not in dim_coord_dims): dim_coords_and_dims.append((coord, dims)) dim_coord_dims.add(dims[0]) else: aux_coords_and_dims.append((coord, dims)) # Call "time" rules. # # For "normal" (non-cross-sectional) time values. vector_headers = collation.element_arrays_and_dims # If the collation doesn't define a vector of values for a # particular header then it must be constant over all fields in the # collation. In which case it's safe to get the value from any field. t1, t1_dims = vector_headers.get('t1', (field.t1, ())) t2, t2_dims = vector_headers.get('t2', (field.t2, ())) lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ())) coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim, field.time_unit('hours'), t1, t2, lbft, t1_dims, t2_dims, lbft_dims) # Bind resulting coordinates to dimensions, where suitable. _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # Call "vertical" rules. # # "Normal" (non-cross-sectional) vertical levels blev, blev_dims = vector_headers.get('blev', (field.blev, ())) lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ())) bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ())) bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ())) brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ())) brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ())) brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ())) # Find all the non-trivial dimension values dims = set( filter(None, [ blev_dims, lblev_dims, bhlev_dims, bhrlev_dims, brsvd1_dims, brsvd2_dims, brlev_dims ])) if len(dims) > 1: raise TranslationError('Unsupported multiple values for vertical ' 'dimension.') if dims: v_dims = dims.pop() if len(v_dims) > 1: raise TranslationError('Unsupported multi-dimension vertical ' 'headers.') else: v_dims = () coords_and_dims, factories = _convert_vertical_coords( field.lbcode, field.lbvc, blev, lblev, field.stash, bhlev, bhrlev, brsvd1, brsvd2, brlev, v_dims) # Bind resulting coordinates to dimensions, where suitable. _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # Realization (aka ensemble) (--> scalar coordinates) aux_coords_and_dims.extend( _convert_scalar_realization_coords(lbrsvd4=field.lbrsvd[3])) # Pseudo-level coordinate (--> scalar coordinates) aux_coords_and_dims.extend( _convert_scalar_pseudo_level_coords(lbuser5=field.lbuser[4])) return ConversionMetadata(factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)
def _convert_collation(collation): """ Converts a FieldCollation into the corresponding items of Cube metadata. Args: * collation: A FieldCollation object. Returns: A :class:`iris.fileformats.rules.ConversionMetadata` object. .. note: This is the 'loader.converter', in the control structure passed to the generic rules code, :meth:`iris.fileformats.rules.load_cubes`. """ from iris.fileformats.rules import ConversionMetadata from iris.fileformats.pp_rules import (_convert_time_coords, _convert_vertical_coords, _convert_scalar_realization_coords, _convert_scalar_pseudo_level_coords, _all_other_rules) # For all the scalar conversions, all fields in the collation will # give the same result, so the choice is arbitrary. field = collation.fields[0] # Call "all other" rules. (references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field) # Adjust any dimension bindings to account for the extra leading # dimensions added by the collation. if collation.vector_dims_shape: def _adjust_dims(coords_and_dims, n_dims): def adjust(dims): if dims is not None: dims += n_dims return dims return [(coord, adjust(dims)) for coord, dims in coords_and_dims] n_collation_dims = len(collation.vector_dims_shape) dim_coords_and_dims = _adjust_dims(dim_coords_and_dims, n_collation_dims) aux_coords_and_dims = _adjust_dims(aux_coords_and_dims, n_collation_dims) # Dimensions to which we've already assigned dimension coordinates. dim_coord_dims = set() # Helper call to choose which coords are dimensions and which auxiliary. def _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims): def key_func(item): return _HINTS.get(item[0].name(), len(_HINTS)) # Target the first DimCoord for a dimension at dim_coords, # and target everything else at aux_coords. for coord, dims in sorted(coords_and_dims, key=key_func): if (isinstance(coord, DimCoord) and dims is not None and len(dims) == 1 and dims[0] not in dim_coord_dims): dim_coords_and_dims.append((coord, dims)) dim_coord_dims.add(dims[0]) else: aux_coords_and_dims.append((coord, dims)) # Call "time" rules. # # For "normal" (non-cross-sectional) time values. vector_headers = collation.element_arrays_and_dims # If the collation doesn't define a vector of values for a # particular header then it must be constant over all fields in the # collation. In which case it's safe to get the value from any field. t1, t1_dims = vector_headers.get('t1', (field.t1, ())) t2, t2_dims = vector_headers.get('t2', (field.t2, ())) lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ())) coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim, field.time_unit('hours'), t1, t2, lbft, t1_dims, t2_dims, lbft_dims) # Bind resulting coordinates to dimensions, where suitable. _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # Call "vertical" rules. # # "Normal" (non-cross-sectional) vertical levels blev, blev_dims = vector_headers.get('blev', (field.blev, ())) lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ())) bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ())) bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ())) brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ())) brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ())) brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ())) # Find all the non-trivial dimension values dims = set(filter(None, [blev_dims, lblev_dims, bhlev_dims, bhrlev_dims, brsvd1_dims, brsvd2_dims, brlev_dims])) if len(dims) > 1: raise TranslationError('Unsupported multiple values for vertical ' 'dimension.') if dims: v_dims = dims.pop() if len(v_dims) > 1: raise TranslationError('Unsupported multi-dimension vertical ' 'headers.') else: v_dims = () coords_and_dims, factories = _convert_vertical_coords(field.lbcode, field.lbvc, blev, lblev, field.stash, bhlev, bhrlev, brsvd1, brsvd2, brlev, v_dims) # Bind resulting coordinates to dimensions, where suitable. _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # Realization (aka ensemble) (--> scalar coordinates) aux_coords_and_dims.extend(_convert_scalar_realization_coords( lbrsvd4=field.lbrsvd[3])) # Pseudo-level coordinate (--> scalar coordinates) aux_coords_and_dims.extend(_convert_scalar_pseudo_level_coords( lbuser5=field.lbuser[4])) return ConversionMetadata(factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)
def _convert_collation(collation): """ Converts a FieldCollation into the corresponding items of Cube metadata. Args: * collation: A FieldCollation object. Returns: A :class:`iris.fileformats.rules.ConversionMetadata` object. """ # For all the scalar conversions all fields in the collation will # give the same result, so the choice is arbitrary. field = collation.fields[0] # All the "other" rules. (references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field) # Adjust any dimension bindings to account for the extra leading # dimensions added by the collation. if collation.vector_dims_shape: n_collation_dims = len(collation.vector_dims_shape) dim_coords_and_dims = _adjust_dims(dim_coords_and_dims, n_collation_dims) aux_coords_and_dims = _adjust_dims(aux_coords_and_dims, n_collation_dims) # "Normal" (non-cross-sectional) time values vector_headers = collation.element_arrays_and_dims # If the collation doesn't define a vector of values for a # particular header then it must be constant over all fields in the # collation. In which case it's safe to get the value from any field. t1, t1_dims = vector_headers.get('t1', (field.t1, ())) t2, t2_dims = vector_headers.get('t2', (field.t2, ())) lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ())) coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim, field.time_unit('hours'), t1, t2, lbft, t1_dims, t2_dims, lbft_dims) dim_coord_dims = set() _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # "Normal" (non-cross-sectional) vertical levels blev, blev_dims = vector_headers.get('blev', (field.blev, ())) lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ())) bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ())) bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ())) brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ())) brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ())) brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ())) # Find all the non-trivial dimension values dims = set(filter(None, [blev_dims, lblev_dims, bhlev_dims, bhrlev_dims, brsvd1_dims, brsvd2_dims, brlev_dims])) if len(dims) > 1: raise TranslationError('Unsupported multiple values for vertical ' 'dimension.') if dims: v_dims = dims.pop() if len(v_dims) > 1: raise TranslationError('Unsupported multi-dimension vertical ' 'headers.') else: v_dims = () coords_and_dims, factories = _convert_vertical_coords(field.lbcode, field.lbvc, blev, lblev, field.stash, bhlev, bhrlev, brsvd1, brsvd2, brlev, v_dims) _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # Realization (aka ensemble) (--> scalar coordinates) aux_coords_and_dims.extend(_convert_scalar_realization_coords( lbrsvd4=field.lbrsvd[3])) # Pseudo-level coordinate (--> scalar coordinates) aux_coords_and_dims.extend(_convert_scalar_pseudo_level_coords( lbuser5=field.lbuser[4])) return ConversionMetadata(factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)
def _convert_collation(collation): """ Converts a FieldCollation into the corresponding items of Cube metadata. Args: * collation: A FieldCollation object. Returns: A :class:`iris.fileformats.rules.ConversionMetadata` object. """ # For all the scalar conversions all fields in the collation will # give the same result, so the choice is arbitrary. field = collation.fields[0] # All the "other" rules. (references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field) # Adjust any dimension bindings to account for the extra leading # dimensions added by the collation. if collation.vector_dims_shape: n_collation_dims = len(collation.vector_dims_shape) dim_coords_and_dims = _adjust_dims(dim_coords_and_dims, n_collation_dims) aux_coords_and_dims = _adjust_dims(aux_coords_and_dims, n_collation_dims) # "Normal" (non-cross-sectional) time values vector_headers = collation.element_arrays_and_dims # If the collation doesn't define a vector of values for a # particular header then it must be constant over all fields in the # collation. In which case it's safe to get the value from any field. t1, t1_dims = vector_headers.get('t1', (field.t1, ())) t2, t2_dims = vector_headers.get('t2', (field.t2, ())) lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ())) coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim, field.time_unit('hours'), t1, t2, lbft, t1_dims, t2_dims, lbft_dims) dim_coord_dims = set() _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # "Normal" (non-cross-sectional) vertical levels blev, blev_dims = vector_headers.get('blev', (field.blev, ())) lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ())) bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ())) bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ())) brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ())) brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ())) brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ())) # Find all the non-trivial dimension values dims = set( filter(None, [ blev_dims, lblev_dims, bhlev_dims, bhrlev_dims, brsvd1_dims, brsvd2_dims, brlev_dims ])) if len(dims) > 1: raise TranslationError('Unsupported multiple values for vertical ' 'dimension.') if dims: v_dims = dims.pop() if len(v_dims) > 1: raise TranslationError('Unsupported multi-dimension vertical ' 'headers.') else: v_dims = () coords_and_dims, factories = _convert_vertical_coords( field.lbcode, field.lbvc, blev, lblev, field.stash, bhlev, bhrlev, brsvd1, brsvd2, brlev, v_dims) _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims) # Realization (aka ensemble) (--> scalar coordinates) aux_coords_and_dims.extend( _convert_scalar_realization_coords(lbrsvd4=field.lbrsvd[3])) # Pseudo-level coordinate (--> scalar coordinates) aux_coords_and_dims.extend( _convert_scalar_pseudo_level_coords(lbuser5=field.lbuser[4])) return ConversionMetadata(factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)