def test_grib1_hybrid_height(self): gm = gribapi.grib_new_from_samples('regular_gg_ml_grib1') gw = GribWrapper(gm) results = grib1_convert(gw) factory, = results[0] self.assertEqual(factory.factory_class, iris.aux_factory.HybridPressureFactory) delta, sigma, ref = factory.args self.assertEqual(delta, {'long_name': 'level_pressure'}) self.assertEqual(sigma, {'long_name': 'sigma'}) self.assertEqual(ref, Reference(name='surface_pressure')) ml_ref = iris.coords.CoordDefn('model_level_number', None, None, cf_units.Unit('1'), {'positive': 'up'}, None, False) lp_ref = iris.coords.CoordDefn(None, 'level_pressure', None, cf_units.Unit('Pa'), {}, None, False) s_ref = iris.coords.CoordDefn(None, 'sigma', None, cf_units.Unit('1'), {}, None, False) aux_coord_defns = [coord._as_defn() for coord, dim in results[8]] self.assertIn(ml_ref, aux_coord_defns) self.assertIn(lp_ref, aux_coord_defns) self.assertIn(s_ref, aux_coord_defns)
def converter(field): if field is press_field: src = param_cube factories = [ Factory(HybridHeightFactory, [Reference("orography")]) ] references = [] else: src = orog_cube factories = [] references = [ReferenceTarget("orography", None)] dim_coords_and_dims = [(coord, src.coord_dims(coord)[0]) for coord in src.dim_coords] aux_coords_and_dims = [(coord, src.coord_dims(coord)) for coord in src.aux_coords] return ConversionMetadata( factories, references, src.standard_name, src.long_name, src.units, src.attributes, src.cell_methods, dim_coords_and_dims, aux_coords_and_dims, )
def test_grib1_hybrid_height(self): gm = gribapi.grib_new_from_samples('regular_gg_ml_grib1') gw = GribWrapper(gm) results = grib1_convert(gw) factory, = results[0] self.assertEqual(factory.factory_class, HybridPressureFactory) delta, sigma, ref = factory.args self.assertEqual(delta, {'long_name': 'level_pressure'}) self.assertEqual(sigma, {'long_name': 'sigma'}) self.assertEqual(ref, Reference(name='surface_pressure')) coords_and_dims = results[8] coord, = [ co for co, _ in coords_and_dims if co.name() == 'model_level_number' ] self.assertEqual(coord.units, '1') self.assertEqual(coord.attributes['positive'], 'up') coord, = [ co for co, _ in coords_and_dims if co.name() == 'level_pressure' ] self.assertEqual(coord.units, 'Pa') coord, = [co for co, _ in coords_and_dims if co.name() == 'sigma'] self.assertEqual(coord.units, '1')
def test_cross_reference(self): # Test the creation process for a factory definition which uses # a cross-reference. param_cube = stock.realistic_4d_no_derived() orog_coord = param_cube.coord('surface_altitude') param_cube.remove_coord(orog_coord) orog_cube = param_cube[0, 0, :, :] orog_cube.data = orog_coord.points orog_cube.rename('surface_altitude') orog_cube.units = orog_coord.units orog_cube.attributes = orog_coord.attributes # We're going to test for the presence of the hybrid height # stuff later, so let's make sure it's not already there! assert len(param_cube.aux_factories) == 0 assert not param_cube.coords('surface_altitude') press_field = Mock() orog_field = Mock() field_generator = lambda filename: [press_field, orog_field] # A fake rule set returning: # 1) A parameter cube needing an "orography" reference # 2) An "orography" cube factory = Factory(HybridHeightFactory, [Reference('orography')]) press_rule_result = RuleResult(param_cube, Mock(), [factory]) orog_rule_result = RuleResult(orog_cube, Mock(), []) rules = Mock() rules.result = lambda field: \ press_rule_result if field is press_field else orog_rule_result # A fake cross-reference rule set ref = ReferenceTarget('orography', None) orog_xref_rule = Mock() orog_xref_rule.run_actions = lambda cube, field: (ref, ) xref_rules = Mock() xref_rules.matching_rules = lambda field: \ [orog_xref_rule] if field is orog_field else [] # Finish by making a fake Loader name = 'FAKE_PP' fake_loader = Loader(field_generator, {}, rules, xref_rules, name) cubes = load_cubes(['fake_filename'], None, fake_loader) # Check the result is a generator containing both of our cubes. self.assertIsInstance(cubes, types.GeneratorType) cubes = list(cubes) self.assertEqual(len(cubes), 2) self.assertIs(cubes[0], orog_cube) self.assertIs(cubes[1], param_cube) # Check the "cube" has an "aux_factory" added, which itself # must have been created with the correct arguments. self.assertEqual(len(param_cube.aux_factories), 1) self.assertEqual(len(param_cube.coords('surface_altitude')), 1)
def convert(grib): """ Converts a GRIB message into the corresponding items of Cube metadata. Args: * grib: A :class:`~iris.fileformats.grib.GribWrapper` object. Returns: A :class:`iris.fileformats.rules.ConversionMetadata` object. """ factories = [] references = [] standard_name = None long_name = None units = None attributes = {} cell_methods = [] dim_coords_and_dims = [] aux_coords_and_dims = [] # deprecation warning for this code path for edition 2 messages if grib.edition == 2: msg = ('This GRIB loader is deprecated and will be removed in ' 'a future release. Please consider using the new ' 'GRIB loader by setting the :class:`iris.Future` ' 'option `strict_grib_load` to True; e.g.:\n' 'iris.FUTURE.strict_grib_load = True\n' 'Please report issues you experience to:\n' 'https://groups.google.com/forum/#!topic/scitools-iris-dev/' 'lMsOusKNfaU') warn_deprecated(msg) if \ (grib.gridType=="reduced_gg"): aux_coords_and_dims.append( (AuxCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) aux_coords_and_dims.append( (AuxCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system), 0)) if \ (grib.gridType=="regular_ll") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="regular_ll") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if \ (grib.gridType=="regular_gg") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="regular_gg") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if \ (grib.gridType=="rotated_ll") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="rotated_ll") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if grib.gridType in ["polar_stereographic", "lambert"]: dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units="m", coord_system=grib._coord_system), 0)) dim_coords_and_dims.append( (DimCoord(grib._x_points, grib._x_coord_name, units="m", coord_system=grib._coord_system), 1)) if \ (grib.edition == 1) and \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 11) and \ (grib._cf_data is None): standard_name = "air_temperature" units = "kelvin" if \ (grib.edition == 1) and \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 33) and \ (grib._cf_data is None): standard_name = "x_wind" units = "m s-1" if \ (grib.edition == 1) and \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 34) and \ (grib._cf_data is None): standard_name = "y_wind" units = "m s-1" if \ (grib.edition == 1) and \ (grib._cf_data is not None): standard_name = grib._cf_data.standard_name long_name = grib._cf_data.standard_name or grib._cf_data.long_name units = grib._cf_data.units if \ (grib.edition == 1) and \ (grib.table2Version >= 128) and \ (grib._cf_data is None): long_name = "UNKNOWN LOCAL PARAM " + str( grib.indicatorOfParameter) + "." + str(grib.table2Version) units = "???" if \ (grib.edition == 1) and \ (grib.table2Version == 1) and \ (grib.indicatorOfParameter >= 128): long_name = "UNKNOWN LOCAL PARAM " + str( grib.indicatorOfParameter) + "." + str(grib.table2Version) units = "???" if \ (grib.edition == 2) and \ (grib._cf_data is not None): standard_name = grib._cf_data.standard_name long_name = grib._cf_data.long_name units = grib._cf_data.units if \ (grib.edition == 1) and \ (grib._phenomenonDateTime != -1.0): aux_coords_and_dims.append( (DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append( (DimCoord(points=grib.phenomenon_points('hours'), standard_name='time', units=Unit('hours since epoch', CALENDAR_GREGORIAN)), None)) def add_bounded_time_coords(aux_coords_and_dims, grib): t_bounds = grib.phenomenon_bounds('hours') period = Unit('hours').convert(t_bounds[1] - t_bounds[0], grib._forecastTimeUnit) aux_coords_and_dims.append( (DimCoord(standard_name='forecast_period', units=grib._forecastTimeUnit, points=grib._forecastTime + 0.5 * period, bounds=[grib._forecastTime, grib._forecastTime + period]), None)) aux_coords_and_dims.append( (DimCoord(standard_name='time', units=Unit('hours since epoch', CALENDAR_GREGORIAN), points=0.5 * (t_bounds[0] + t_bounds[1]), bounds=t_bounds), None)) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 2): add_bounded_time_coords(aux_coords_and_dims, grib) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 3): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 4): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 5): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("_difference", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 51): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 113): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 114): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 115): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 116): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 117): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 118): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("_covariance", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 123): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 124): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 125): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("standard_deviation", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 0): aux_coords_and_dims.append( (DimCoord(points=Unit(grib._forecastTimeUnit).convert( np.int32(grib._forecastTime), "hours"), standard_name='forecast_period', units="hours"), None)) aux_coords_and_dims.append( (DimCoord(points=grib.phenomenon_points('hours'), standard_name='time', units=Unit('hours since epoch', CALENDAR_GREGORIAN)), None)) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber in (8, 9)): add_bounded_time_coords(aux_coords_and_dims, grib) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 0): cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 1): cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 2): cell_methods.append(CellMethod("maximum", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 3): cell_methods.append(CellMethod("minimum", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 4): cell_methods.append(CellMethod("_difference", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 5): cell_methods.append(CellMethod("_root_mean_square", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 6): cell_methods.append(CellMethod("standard_deviation", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 7): cell_methods.append(CellMethod("_convariance", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 8): cell_methods.append(CellMethod("_difference", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 9): cell_methods.append(CellMethod("_ratio", coords="time")) if \ (grib.edition == 1) and \ (grib.levelType == 'pl'): aux_coords_and_dims.append((DimCoord(points=grib.level, long_name="pressure", units="hPa"), None)) if \ (grib.edition == 1) and \ (grib.levelType == 'sfc'): if (grib._cf_data is not None) and \ (grib._cf_data.set_height is not None): aux_coords_and_dims.append( (DimCoord(points=grib._cf_data.set_height, long_name="height", units="m", attributes={'positive': 'up'}), None)) elif grib.typeOfLevel == 'heightAboveGround': # required for NCAR aux_coords_and_dims.append((DimCoord(points=grib.level, long_name="height", units="m", attributes={'positive': 'up'}), None)) if \ (grib.edition == 1) and \ (grib.levelType == 'ml') and \ (hasattr(grib, 'pv')): aux_coords_and_dims.append( (AuxCoord(grib.level, standard_name='model_level_number', attributes={'positive': 'up'}), None)) aux_coords_and_dims.append((DimCoord(grib.pv[grib.level], long_name='level_pressure', units='Pa'), None)) aux_coords_and_dims.append((AuxCoord( grib.pv[grib.numberOfCoordinatesValues // 2 + grib.level], long_name='sigma'), None)) factories.append( Factory(HybridPressureFactory, [{ 'long_name': 'level_pressure' }, { 'long_name': 'sigma' }, Reference('surface_pressure')])) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface != grib.typeOfSecondFixedSurface): warnings.warn("Different vertical bound types not yet handled.") if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 103) and \ (grib.typeOfSecondFixedSurface == 255): aux_coords_and_dims.append( (DimCoord(points=grib.scaledValueOfFirstFixedSurface / (10.0**grib.scaleFactorOfFirstFixedSurface), standard_name="height", units="m"), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 103) and \ (grib.typeOfSecondFixedSurface != 255): aux_coords_and_dims.append((DimCoord( points=0.5 * (grib.scaledValueOfFirstFixedSurface / (10.0**grib.scaleFactorOfFirstFixedSurface) + grib.scaledValueOfSecondFixedSurface / (10.0**grib.scaleFactorOfSecondFixedSurface)), standard_name="height", units="m", bounds=[ grib.scaledValueOfFirstFixedSurface / (10.0**grib.scaleFactorOfFirstFixedSurface), grib.scaledValueOfSecondFixedSurface / (10.0**grib.scaleFactorOfSecondFixedSurface) ]), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 100) and \ (grib.typeOfSecondFixedSurface == 255): aux_coords_and_dims.append( (DimCoord(points=grib.scaledValueOfFirstFixedSurface / (10.0**grib.scaleFactorOfFirstFixedSurface), long_name="pressure", units="Pa"), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 100) and \ (grib.typeOfSecondFixedSurface != 255): aux_coords_and_dims.append((DimCoord( points=0.5 * (grib.scaledValueOfFirstFixedSurface / (10.0**grib.scaleFactorOfFirstFixedSurface) + grib.scaledValueOfSecondFixedSurface / (10.0**grib.scaleFactorOfSecondFixedSurface)), long_name="pressure", units="Pa", bounds=[ grib.scaledValueOfFirstFixedSurface / (10.0**grib.scaleFactorOfFirstFixedSurface), grib.scaledValueOfSecondFixedSurface / (10.0**grib.scaleFactorOfSecondFixedSurface) ]), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface in [105, 119]) and \ (grib.numberOfCoordinatesValues > 0): aux_coords_and_dims.append( (AuxCoord(grib.scaledValueOfFirstFixedSurface, standard_name='model_level_number', attributes={'positive': 'up'}), None)) aux_coords_and_dims.append( (DimCoord(grib.pv[grib.scaledValueOfFirstFixedSurface], long_name='level_pressure', units='Pa'), None)) aux_coords_and_dims.append( (AuxCoord(grib.pv[grib.numberOfCoordinatesValues // 2 + grib.scaledValueOfFirstFixedSurface], long_name='sigma'), None)) factories.append( Factory(HybridPressureFactory, [{ 'long_name': 'level_pressure' }, { 'long_name': 'sigma' }, Reference('surface_air_pressure')])) if grib._originatingCentre != 'unknown': aux_coords_and_dims.append((AuxCoord(points=grib._originatingCentre, long_name='originating_centre', units='no_unit'), None)) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 1): aux_coords_and_dims.append((DimCoord(points=grib.perturbationNumber, long_name='ensemble_member', units='no_unit'), None)) if \ (grib.edition == 2) and \ grib.productDefinitionTemplateNumber not in (0, 8): attributes["GRIB_LOAD_WARNING"] = ( "unsupported GRIB%d ProductDefinitionTemplate: #4.%d" % (grib.edition, grib.productDefinitionTemplateNumber)) if \ (grib.edition == 2) and \ (grib.centre == 'ecmf') and \ (grib.discipline == 0) and \ (grib.parameterCategory == 3) and \ (grib.parameterNumber == 25) and \ (grib.typeOfFirstFixedSurface == 105): references.append( ReferenceTarget( 'surface_air_pressure', lambda cube: { 'standard_name': 'surface_air_pressure', 'units': 'Pa', 'data': np.exp(cube.data) })) return ConversionMetadata(factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)
def convert(grib): factories = [] references = [] standard_name = None long_name = None units = None attributes = {} cell_methods = [] dim_coords_and_dims = [] aux_coords_and_dims = [] if \ (grib.gridType=="regular_ll") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append((DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="regular_ll") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append((DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if \ (grib.gridType=="regular_gg") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append((DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="regular_gg") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append((DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if \ (grib.gridType=="rotated_ll") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append((DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="rotated_ll") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append((DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if grib.gridType in ["polar_stereographic", "lambert"]: dim_coords_and_dims.append((DimCoord(grib._y_points, grib._y_coord_name, units="m", coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units="m", coord_system=grib._coord_system), 1)) if \ (grib.edition == 1) and \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 11) and \ (grib._cf_data is None): standard_name = "air_temperature" units = "kelvin" if \ (grib.edition == 1) and \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 33) and \ (grib._cf_data is None): standard_name = "x_wind" units = "m s-1" if \ (grib.edition == 1) and \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 34) and \ (grib._cf_data is None): standard_name = "y_wind" units = "m s-1" if \ (grib.edition == 1) and \ (grib._cf_data is not None): standard_name = grib._cf_data.standard_name long_name = grib._cf_data.standard_name or grib._cf_data.long_name units = grib._cf_data.units if \ (grib.edition == 1) and \ (grib.table2Version >= 128) and \ (grib._cf_data is None): long_name = "UNKNOWN LOCAL PARAM " + str(grib.indicatorOfParameter) + "." + str(grib.table2Version) units = "???" if \ (grib.edition == 1) and \ (grib.table2Version == 1) and \ (grib.indicatorOfParameter >= 128): long_name = "UNKNOWN LOCAL PARAM " + str(grib.indicatorOfParameter) + "." + str(grib.table2Version) units = "???" if \ (grib.edition == 2) and \ (grib._cf_data is not None): standard_name = grib._cf_data.standard_name long_name = grib._cf_data.long_name units = grib._cf_data.units if \ (grib.edition == 1) and \ (grib._phenomenonDateTime != -1.0): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_points('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 3): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 4): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 5): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("_difference", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 51): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 113): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 114): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 115): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 116): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 117): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 118): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("_covariance", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 123): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 124): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 1) and \ (grib.timeRangeIndicator == 125): aux_coords_and_dims.append((DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], bounds=grib.phenomenon_bounds('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) cell_methods.append(CellMethod("standard_deviation", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 0): aux_coords_and_dims.append((DimCoord(points=Unit(grib._forecastTimeUnit).convert(np.int32(grib._forecastTime), "hours"), standard_name='forecast_period', units="hours"), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_points('hours'), standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN)), None)) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber in (8, 9)): aux_coords_and_dims.append((DimCoord(points=Unit(grib._forecastTimeUnit).convert(np.int32(grib._forecastTime), "hours"), standard_name='forecast_period', units="hours"), None)) aux_coords_and_dims.append((DimCoord(points=grib.phenomenon_bounds('hours')[0], standard_name='time', units=Unit('hours since epoch', iris.unit.CALENDAR_GREGORIAN), bounds=grib.phenomenon_bounds('hours')), None)) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 0): cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 1): cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 2): cell_methods.append(CellMethod("maximum", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 3): cell_methods.append(CellMethod("minimum", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 4): cell_methods.append(CellMethod("_difference", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 5): cell_methods.append(CellMethod("_root_mean_square", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 6): cell_methods.append(CellMethod("standard_deviation", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 7): cell_methods.append(CellMethod("_convariance", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 8): cell_methods.append(CellMethod("_difference", coords="time")) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 8) and \ (grib.typeOfStatisticalProcessing == 9): cell_methods.append(CellMethod("_ratio", coords="time")) if \ (grib.edition == 1) and \ (grib.levelType == 'pl'): aux_coords_and_dims.append((DimCoord(points=grib.level, long_name="pressure", units="hPa"), None)) if \ (grib.edition == 1) and \ (grib.levelType == 'sfc') and \ (grib._cf_data is not None) and \ (grib._cf_data.set_height is not None): aux_coords_and_dims.append((DimCoord(points=grib._cf_data.set_height, long_name="height", units="m", attributes={'positive':'up'}), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface != grib.typeOfSecondFixedSurface): warnings.warn("Different vertical bound types not yet handled.") if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 103) and \ (grib.typeOfSecondFixedSurface == 255): aux_coords_and_dims.append((DimCoord(points=grib.scaledValueOfFirstFixedSurface/(10.0**grib.scaleFactorOfFirstFixedSurface), standard_name="height", units="m"), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 103) and \ (grib.typeOfSecondFixedSurface != 255): aux_coords_and_dims.append((DimCoord(points=0.5*(grib.scaledValueOfFirstFixedSurface/(10.0**grib.scaleFactorOfFirstFixedSurface) + grib.scaledValueOfSecondFixedSurface/(10.0**grib.scaleFactorOfSecondFixedSurface)), standard_name="height", units="m", bounds=[grib.scaledValueOfFirstFixedSurface/(10.0**grib.scaleFactorOfFirstFixedSurface) , grib.scaledValueOfSecondFixedSurface/(10.0**grib.scaleFactorOfSecondFixedSurface)]), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 100) and \ (grib.typeOfSecondFixedSurface == 255): aux_coords_and_dims.append((DimCoord(points=grib.scaledValueOfFirstFixedSurface/(10.0**grib.scaleFactorOfFirstFixedSurface), long_name="pressure", units="Pa"), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface == 100) and \ (grib.typeOfSecondFixedSurface != 255): aux_coords_and_dims.append((DimCoord(points=0.5*(grib.scaledValueOfFirstFixedSurface/(10.0**grib.scaleFactorOfFirstFixedSurface) + grib.scaledValueOfSecondFixedSurface/(10.0**grib.scaleFactorOfSecondFixedSurface)), long_name="pressure", units="Pa", bounds=[grib.scaledValueOfFirstFixedSurface/(10.0**grib.scaleFactorOfFirstFixedSurface) , grib.scaledValueOfSecondFixedSurface/(10.0**grib.scaleFactorOfSecondFixedSurface)]), None)) if \ (grib.edition == 2) and \ (grib.typeOfFirstFixedSurface in [105, 119]) and \ (grib.numberOfCoordinatesValues > 0): aux_coords_and_dims.append((AuxCoord(grib.scaledValueOfFirstFixedSurface, standard_name='model_level_number', attributes={'positive': 'up'}), None)) aux_coords_and_dims.append((DimCoord(grib.pv[grib.scaledValueOfFirstFixedSurface], long_name='level_pressure', units='Pa'), None)) aux_coords_and_dims.append((AuxCoord(grib.pv[grib.numberOfCoordinatesValues/2 + grib.scaledValueOfFirstFixedSurface], long_name='sigma'), None)) factories.append(Factory(HybridPressureFactory, [{'long_name': 'level_pressure'}, {'long_name': 'sigma'}, Reference('surface_pressure')])) if grib._originatingCentre != 'unknown': aux_coords_and_dims.append((AuxCoord(points=grib._originatingCentre, long_name='originating_centre', units='no_unit'), None)) if \ (grib.edition == 2) and \ (grib.productDefinitionTemplateNumber == 1): aux_coords_and_dims.append((DimCoord(points=grib.perturbationNumber, long_name='ensemble_member', units='no_unit'), None)) if grib.productDefinitionTemplateNumber not in (0, 8): attributes["GRIB_LOAD_WARNING"] = ("unsupported GRIB%d ProductDefinitionTemplate: #4.%d" % (grib.edition, grib.productDefinitionTemplateNumber)) if \ (grib.edition == 2) and \ (grib.centre == 'ecmf') and \ (grib.discipline == 0) and \ (grib.parameterCategory == 3) and \ (grib.parameterNumber == 25) and \ (grib.typeOfFirstFixedSurface == 105): references.append(ReferenceTarget('surface_pressure', lambda cube: {'standard_name': 'surface_air_pressure', 'units': 'Pa', 'data': np.exp(cube.data)})) return (factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)
def convert(f): factories = [] references = [] standard_name = None long_name = None units = None attributes = {} cell_methods = [] dim_coords_and_dims = [] aux_coords_and_dims = [] if \ (f.lbtim.ia == 0) and \ (f.lbtim.ib == 0) and \ (f.lbtim.ic in [1, 2, 3, 4]) and \ (len(f.lbcode) != 5 or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])): aux_coords_and_dims.append( (DimCoord(f.time_unit('hours').date2num(f.t1), standard_name='time', units=f.time_unit('hours')), None)) if \ (f.lbtim.ia == 0) and \ (f.lbtim.ib == 1) and \ (f.lbtim.ic in [1, 2, 3, 4]) and \ (len(f.lbcode) != 5 or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])): aux_coords_and_dims.append((DimCoord(f.time_unit('hours', f.t2).date2num(f.t1), standard_name='forecast_period', units='hours'), None)) aux_coords_and_dims.append( (DimCoord(f.time_unit('hours').date2num(f.t1), standard_name='time', units=f.time_unit('hours')), None)) aux_coords_and_dims.append( (DimCoord(f.time_unit('hours').date2num(f.t2), standard_name='forecast_reference_time', units=f.time_unit('hours')), None)) if \ (f.lbtim.ib == 2) and \ (f.lbtim.ic in [1, 2, 4]) and \ ((len(f.lbcode) != 5) or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])): t_unit = f.time_unit('hours') t1_hours = t_unit.date2num(f.t1) t2_hours = t_unit.date2num(f.t2) period = t2_hours - t1_hours aux_coords_and_dims.append((DimCoord(standard_name='forecast_period', units='hours', points=f.lbft - 0.5 * period, bounds=[f.lbft - period, f.lbft]), None)) aux_coords_and_dims.append( (DimCoord(standard_name='time', units=t_unit, points=0.5 * (t1_hours + t2_hours), bounds=[t1_hours, t2_hours]), None)) aux_coords_and_dims.append( (DimCoord(f.time_unit('hours').date2num(f.t2) - f.lbft, standard_name='forecast_reference_time', units=f.time_unit('hours')), None)) if \ (f.lbtim.ib == 3) and \ (f.lbtim.ic in [1, 2, 4]) and \ ((len(f.lbcode) != 5) or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])): t_unit = f.time_unit('hours') t1_hours = t_unit.date2num(f.t1) t2_hours = t_unit.date2num(f.t2) period = t2_hours - t1_hours aux_coords_and_dims.append((DimCoord(standard_name='forecast_period', units='hours', points=f.lbft, bounds=[f.lbft - period, f.lbft]), None)) aux_coords_and_dims.append((DimCoord(standard_name='time', units=t_unit, points=t2_hours, bounds=[t1_hours, t2_hours]), None)) aux_coords_and_dims.append( (DimCoord(f.time_unit('hours').date2num(f.t2) - f.lbft, standard_name='forecast_reference_time', units=f.time_unit('hours')), None)) if \ (f.lbtim.ib == 3) and \ (f.lbtim.ic in [1, 2, 4]) and \ ((len(f.lbcode) != 5) or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])) and \ (f.lbmon == 12 and f.lbdat == 1 and f.lbhr == 0 and f.lbmin == 0) and \ (f.lbmond == 3 and f.lbdatd == 1 and f.lbhrd == 0 and f.lbmind == 0): aux_coords_and_dims.append((AuxCoord('djf', long_name='season', units='no_unit'), None)) if \ (f.lbtim.ib == 3) and \ (f.lbtim.ic in [1, 2, 4]) and \ ((len(f.lbcode) != 5) or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])) and \ (f.lbmon == 3 and f.lbdat == 1 and f.lbhr == 0 and f.lbmin == 0) and \ (f.lbmond == 6 and f.lbdatd == 1 and f.lbhrd == 0 and f.lbmind == 0): aux_coords_and_dims.append((AuxCoord('mam', long_name='season', units='no_unit'), None)) if \ (f.lbtim.ib == 3) and \ (f.lbtim.ic in [1, 2, 4]) and \ ((len(f.lbcode) != 5) or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])) and \ (f.lbmon == 6 and f.lbdat == 1 and f.lbhr == 0 and f.lbmin == 0) and \ (f.lbmond == 9 and f.lbdatd == 1 and f.lbhrd == 0 and f.lbmind == 0): aux_coords_and_dims.append((AuxCoord('jja', long_name='season', units='no_unit'), None)) if \ (f.lbtim.ib == 3) and \ (f.lbtim.ic in [1, 2, 4]) and \ ((len(f.lbcode) != 5) or (len(f.lbcode) == 5 and f.lbcode.ix not in [20, 21, 22, 23] and f.lbcode.iy not in [20, 21, 22, 23])) and \ (f.lbmon == 9 and f.lbdat == 1 and f.lbhr == 0 and f.lbmin == 0) and \ (f.lbmond == 12 and f.lbdatd == 1 and f.lbhrd == 0 and f.lbmind == 0): aux_coords_and_dims.append((AuxCoord('son', long_name='season', units='no_unit'), None)) if \ (f.bdx != 0.0) and \ (f.bdx != f.bmdi) and \ (len(f.lbcode) != 5) and \ (f.lbcode[0] == 1): dim_coords_and_dims.append( (DimCoord.from_regular(f.bzx, f.bdx, f.lbnpt, standard_name=f._x_coord_name(), units='degrees', circular=(f.lbhem in [0, 4]), coord_system=f.coord_system()), 1)) if \ (f.bdx != 0.0) and \ (f.bdx != f.bmdi) and \ (len(f.lbcode) != 5) and \ (f.lbcode[0] == 2): dim_coords_and_dims.append( (DimCoord.from_regular(f.bzx, f.bdx, f.lbnpt, standard_name=f._x_coord_name(), units='degrees', circular=(f.lbhem in [0, 4]), coord_system=f.coord_system(), with_bounds=True), 1)) if \ (f.bdy != 0.0) and \ (f.bdy != f.bmdi) and \ (len(f.lbcode) != 5) and \ (f.lbcode[0] == 1): dim_coords_and_dims.append( (DimCoord.from_regular(f.bzy, f.bdy, f.lbrow, standard_name=f._y_coord_name(), units='degrees', coord_system=f.coord_system()), 0)) if \ (f.bdy != 0.0) and \ (f.bdy != f.bmdi) and \ (len(f.lbcode) != 5) and \ (f.lbcode[0] == 2): dim_coords_and_dims.append( (DimCoord.from_regular(f.bzy, f.bdy, f.lbrow, standard_name=f._y_coord_name(), units='degrees', coord_system=f.coord_system(), with_bounds=True), 0)) if \ (f.bdy == 0.0 or f.bdy == f.bmdi) and \ (len(f.lbcode) != 5 or (len(f.lbcode) == 5 and f.lbcode.iy == 10)): dim_coords_and_dims.append( (DimCoord(f.y, standard_name=f._y_coord_name(), units='degrees', bounds=f.y_bounds, coord_system=f.coord_system()), 0)) if \ (f.bdx == 0.0 or f.bdx == f.bmdi) and \ (len(f.lbcode) != 5 or (len(f.lbcode) == 5 and f.lbcode.ix == 11)): dim_coords_and_dims.append( (DimCoord(f.x, standard_name=f._x_coord_name(), units='degrees', bounds=f.x_bounds, circular=(f.lbhem in [0, 4]), coord_system=f.coord_system()), 1)) if \ (len(f.lbcode) == 5) and \ (f.lbcode.iy == 2) and \ (f.bdy == 0 or f.bdy == f.bmdi): dim_coords_and_dims.append((DimCoord(f.y, standard_name='height', units='km', bounds=f.y_bounds, attributes={'positive': 'up'}), 0)) if \ (len(f.lbcode) == 5) and \ (f.lbcode[-1] == 1) and \ (f.lbcode.iy == 4): dim_coords_and_dims.append((DimCoord(f.y, standard_name='depth', units='m', bounds=f.y_bounds, attributes={'positive': 'down'}), 0)) if \ (len(f.lbcode) == 5) and \ (f.lbcode.ix == 10) and \ (f.bdx != 0) and \ (f.bdx != f.bmdi): dim_coords_and_dims.append( (DimCoord.from_regular(f.bzx, f.bdx, f.lbnpt, standard_name=f._y_coord_name(), units='degrees', coord_system=f.coord_system()), 1)) if \ (len(f.lbcode) == 5) and \ (f.lbcode.iy == 1) and \ (f.bdy == 0 or f.bdy == f.bmdi): dim_coords_and_dims.append((DimCoord(f.y, long_name='pressure', units='hPa', bounds=f.y_bounds), 0)) if \ (len(f.lbcode) == 5) and \ (f.lbcode.ix == 1) and \ (f.bdx == 0 or f.bdx == f.bmdi): dim_coords_and_dims.append((DimCoord(f.x, long_name='pressure', units='hPa', bounds=f.x_bounds), 1)) if \ (len(f.lbcode) == 5) and \ (f.lbcode[-1] == 1) and \ (f.lbcode.iy == 23): dim_coords_and_dims.append((DimCoord( f.y, standard_name='time', units=iris.unit.Unit('days since 0000-01-01 00:00:00', calendar=iris.unit.CALENDAR_360_DAY), bounds=f.y_bounds), 0)) if \ (len(f.lbcode) == 5) and \ (f.lbcode[-1] == 1) and \ (f.lbcode.ix == 23): dim_coords_and_dims.append((DimCoord( f.x, standard_name='time', units=iris.unit.Unit('days since 0000-01-01 00:00:00', calendar=iris.unit.CALENDAR_360_DAY), bounds=f.x_bounds), 1)) if \ (len(f.lbcode) == 5) and \ (f.lbcode[-1] == 1) and \ (f.lbcode.ix == 13) and \ (f.bdx != 0): dim_coords_and_dims.append( (DimCoord.from_regular(f.bzx, f.bdx, f.lbnpt, long_name='site_number', units='1'), 1)) if \ (len(f.lbcode) == 5) and \ (13 in [f.lbcode.ix, f.lbcode.iy]) and \ (11 not in [f.lbcode.ix, f.lbcode.iy]) and \ (hasattr(f, 'lower_x_domain')) and \ (hasattr(f, 'upper_x_domain')) and \ (all(f.lower_x_domain != -1.e+30)) and \ (all(f.upper_x_domain != -1.e+30)): aux_coords_and_dims.append((AuxCoord( (f.lower_x_domain + f.upper_x_domain) / 2.0, standard_name=f._x_coord_name(), units='degrees', bounds=np.array([f.lower_x_domain, f.upper_x_domain]).T, coord_system=f.coord_system()), 1 if f.lbcode.ix == 13 else 0)) if \ (len(f.lbcode) == 5) and \ (13 in [f.lbcode.ix, f.lbcode.iy]) and \ (10 not in [f.lbcode.ix, f.lbcode.iy]) and \ (hasattr(f, 'lower_y_domain')) and \ (hasattr(f, 'upper_y_domain')) and \ (all(f.lower_y_domain != -1.e+30)) and \ (all(f.upper_y_domain != -1.e+30)): aux_coords_and_dims.append((AuxCoord( (f.lower_y_domain + f.upper_y_domain) / 2.0, standard_name=f._y_coord_name(), units='degrees', bounds=np.array([f.lower_y_domain, f.upper_y_domain]).T, coord_system=f.coord_system()), 1 if f.lbcode.ix == 13 else 0)) if \ (f.lbproc == 128) and \ (f.lbtim.ib == 2) and \ (f.lbtim.ia == 0): cell_methods.append(CellMethod("mean", coords="time")) if \ (f.lbproc == 128) and \ (f.lbtim.ib == 2) and \ (f.lbtim.ia != 0): cell_methods.append( CellMethod("mean", coords="time", intervals="%d hour" % f.lbtim.ia)) if \ (f.lbproc == 128) and \ (f.lbtim.ib == 3): cell_methods.append(CellMethod("mean", coords="time")) if \ (f.lbproc == 128) and \ (f.lbtim.ib not in [2, 3]): cell_methods.append(CellMethod("mean", coords="time")) if \ (f.lbproc == 4096) and \ (f.lbtim.ib == 2) and \ (f.lbtim.ia == 0): cell_methods.append(CellMethod("minimum", coords="time")) if \ (f.lbproc == 4096) and \ (f.lbtim.ib == 2) and \ (f.lbtim.ia != 0): cell_methods.append( CellMethod("minimum", coords="time", intervals="%d hour" % f.lbtim.ia)) if \ (f.lbproc == 4096) and \ (f.lbtim.ib != 2): cell_methods.append(CellMethod("minimum", coords="time")) if \ (f.lbproc == 8192) and \ (f.lbtim.ib == 2) and \ (f.lbtim.ia == 0): cell_methods.append(CellMethod("maximum", coords="time")) if \ (f.lbproc == 8192) and \ (f.lbtim.ib == 2) and \ (f.lbtim.ia != 0): cell_methods.append( CellMethod("maximum", coords="time", intervals="%d hour" % f.lbtim.ia)) if \ (f.lbproc == 8192) and \ (f.lbtim.ib != 2): cell_methods.append(CellMethod("maximum", coords="time")) if f.lbproc not in [0, 128, 4096, 8192]: attributes["ukmo__process_flags"] = tuple( sorted([ iris.fileformats.pp.lbproc_map[flag] for flag in f.lbproc.flags ])) if \ (f.lbvc == 1) and \ (not (str(f.stash) in ['m01s03i236', 'm01s03i237', 'm01s03i245', 'm01s03i247', 'm01s03i250'])) and \ (f.blev != -1): aux_coords_and_dims.append((DimCoord(f.blev, standard_name='height', units='m', attributes={'positive': 'up'}), None)) if str(f.stash) in [ 'm01s03i236', 'm01s03i237', 'm01s03i245', 'm01s03i247', 'm01s03i250' ]: aux_coords_and_dims.append((DimCoord(1.5, standard_name='height', units='m', attributes={'positive': 'up'}), None)) if \ (len(f.lbcode) != 5) and \ (f.lbvc == 2): aux_coords_and_dims.append( (DimCoord(_model_level_number(f), standard_name='model_level_number', attributes={'positive': 'down'}), None)) if \ (len(f.lbcode) != 5) and \ (f.lbvc == 2) and \ (f.brsvd[0] == f.brlev): aux_coords_and_dims.append((DimCoord(f.blev, standard_name='depth', units='m', attributes={'positive': 'down'}), None)) if \ (len(f.lbcode) != 5) and \ (f.lbvc == 2) and \ (f.brsvd[0] != f.brlev): aux_coords_and_dims.append((DimCoord(f.blev, standard_name='depth', units='m', bounds=[f.brsvd[0], f.brlev], attributes={'positive': 'down'}), None)) # soil level if len(f.lbcode) != 5 and f.lbvc == 6: aux_coords_and_dims.append( (DimCoord(_model_level_number(f), long_name='soil_model_level_number', attributes={'positive': 'down'}), None)) if \ (f.lbvc == 8) and \ (len(f.lbcode) != 5 or (len(f.lbcode) == 5 and 1 not in [f.lbcode.ix, f.lbcode.iy])): aux_coords_and_dims.append((DimCoord(f.blev, long_name='pressure', units='hPa'), None)) if \ (len(f.lbcode) != 5) and \ (f.lbvc == 19): aux_coords_and_dims.append( (DimCoord(f.blev, standard_name='air_potential_temperature', units='K', attributes={'positive': 'up'}), None)) # Hybrid pressure coordinate if f.lbvc == 9: model_level_number = DimCoord(_model_level_number(f), standard_name='model_level_number', attributes={'positive': 'up'}) # The following match the hybrid height scheme, but data has the # blev and bhlev values the other way around. #level_pressure = DimCoord(f.blev, # long_name='level_pressure', # units='Pa', # bounds=[f.brlev, f.brsvd[0]]) #sigma = AuxCoord(f.bhlev, # long_name='sigma', # bounds=[f.bhrlev, f.brsvd[1]]) level_pressure = DimCoord(f.bhlev, long_name='level_pressure', units='Pa', bounds=[f.bhrlev, f.brsvd[1]]) sigma = AuxCoord(f.blev, long_name='sigma', bounds=[f.brlev, f.brsvd[0]]) aux_coords_and_dims.extend([(model_level_number, None), (level_pressure, None), (sigma, None)]) factories.append( Factory(HybridPressureFactory, [{ 'long_name': 'level_pressure' }, { 'long_name': 'sigma' }, Reference('surface_air_pressure')])) if f.lbvc == 65: aux_coords_and_dims.append( (DimCoord(_model_level_number(f), standard_name='model_level_number', attributes={'positive': 'up'}), None)) aux_coords_and_dims.append((DimCoord(f.blev, long_name='level_height', units='m', bounds=[f.brlev, f.brsvd[0]], attributes={'positive': 'up'}), None)) aux_coords_and_dims.append((AuxCoord(f.bhlev, long_name='sigma', bounds=[f.bhrlev, f.brsvd[1]]), None)) factories.append( Factory(HybridHeightFactory, [{ 'long_name': 'level_height' }, { 'long_name': 'sigma' }, Reference('orography')])) if f.lbrsvd[3] != 0: aux_coords_and_dims.append( (DimCoord(f.lbrsvd[3], standard_name='realization'), None)) if f.lbuser[4] != 0: aux_coords_and_dims.append((DimCoord(f.lbuser[4], long_name='pseudo_level', units='1'), None)) if f.lbuser[6] == 1 and f.lbuser[3] == 5226: standard_name = "precipitation_amount" units = "kg m-2" if \ (f.lbuser[6] == 2) and \ (f.lbuser[3] == 101): standard_name = "sea_water_potential_temperature" units = "Celsius" if \ ((f.lbsrce % 10000) == 1111) and \ ((f.lbsrce / 10000) / 100.0 > 0): attributes['source'] = 'Data from Met Office Unified Model %4.2f' % ( (f.lbsrce / 10000) / 100.0) if \ ((f.lbsrce % 10000) == 1111) and \ ((f.lbsrce / 10000) / 100.0 == 0): attributes['source'] = 'Data from Met Office Unified Model' if f.lbuser[6] != 0 or (f.lbuser[3] / 1000) != 0 or (f.lbuser[3] % 1000) != 0: attributes['STASH'] = f.stash if \ (f.lbuser[6] == 1) and \ (f.lbuser[3] == 4205): standard_name = "mass_fraction_of_cloud_ice_in_air" units = "1" if \ (f.lbuser[6] == 1) and \ (f.lbuser[3] == 4206): standard_name = "mass_fraction_of_cloud_liquid_water_in_air" units = "1" if \ (f.lbuser[6] == 1) and \ (f.lbuser[3] == 30204): standard_name = "air_temperature" units = "K" if \ (f.lbuser[6] == 4) and \ (f.lbuser[3] == 6001): standard_name = "sea_surface_wave_significant_height" units = "m" if str(f.stash) in STASH_TO_CF: standard_name = STASH_TO_CF[str(f.stash)].standard_name units = STASH_TO_CF[str(f.stash)].units long_name = STASH_TO_CF[str(f.stash)].long_name if \ (not f.stash.is_valid) and \ (f.lbfc in LBFC_TO_CF): standard_name = LBFC_TO_CF[f.lbfc].standard_name units = LBFC_TO_CF[f.lbfc].units long_name = LBFC_TO_CF[f.lbfc].long_name if f.lbuser[3] == 33: references.append(ReferenceTarget('orography', None)) if f.lbuser[3] == 409 or f.lbuser[3] == 1: references.append(ReferenceTarget('surface_air_pressure', None)) return (factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)
def _convert_vertical_coords(lbcode, lbvc, blev, lblev, stash, bhlev, bhrlev, brsvd1, brsvd2, brlev, dim=None): """ Encode scalar or vector vertical level values from PP headers as CM data components. Args: * lbcode: Scalar field :class:`iris.fileformats.pp.SplittableInt` value. * lbvc: Scalar field value. * blev: Scalar field value or :class:`numpy.ndarray` vector of field values. * lblev: Scalar field value or :class:`numpy.ndarray` vector of field values. * stash: Scalar field :class:`iris.fileformats.pp.STASH` value. * bhlev: Scalar field value or :class:`numpy.ndarray` vector of field values. * bhrlev: Scalar field value or :class:`numpy.ndarray` vector of field values. * brsvd1: Scalar field value or :class:`numpy.ndarray` vector of field values. * brsvd2: Scalar field value or :class:`numpy.ndarray` vector of field values. * brlev: Scalar field value or :class:`numpy.ndarray` vector of field values. Kwargs: * dim: Associated dimension of the vertical coordinate. Defaults to None. Returns: A tuple containing a list of coords_and_dims, and a list of factories. """ factories = [] coords_and_dims = [] # See Word no. 33 (LBLEV) in section 4 of UM Model Docs (F3). BASE_RHO_LEVEL_LBLEV = 9999 model_level_number = np.atleast_1d(lblev) model_level_number[model_level_number == BASE_RHO_LEVEL_LBLEV] = 0 # Ensure to vectorise these arguments as arrays, as they participate # in the conditions of convert rules. blev = np.atleast_1d(blev) brsvd1 = np.atleast_1d(brsvd1) brlev = np.atleast_1d(brlev) # Height. if (lbvc == 1) and \ str(stash) not in STASHCODE_IMPLIED_HEIGHTS and \ np.all(blev != -1): coord = _dim_or_aux(blev, standard_name='height', units='m', attributes={'positive': 'up'}) coords_and_dims.append((coord, dim)) if str(stash) in STASHCODE_IMPLIED_HEIGHTS: height = STASHCODE_IMPLIED_HEIGHTS[str(stash)] coord = DimCoord(height, standard_name='height', units='m', attributes={'positive': 'up'}) coords_and_dims.append((coord, None)) # Model level number. if (len(lbcode) != 5) and \ (lbvc == 2): coord = _dim_or_aux(model_level_number, standard_name='model_level_number', attributes={'positive': 'down'}) coords_and_dims.append((coord, dim)) # Depth - unbound. if (len(lbcode) != 5) and \ (lbvc == 2) and \ np.all(brsvd1 == brlev): coord = _dim_or_aux(blev, standard_name='depth', units='m', attributes={'positive': 'down'}) coords_and_dims.append((coord, dim)) # Depth - bound. if (len(lbcode) != 5) and \ (lbvc == 2) and \ np.all(brsvd1 != brlev): coord = _dim_or_aux(blev, standard_name='depth', units='m', bounds=np.vstack((brsvd1, brlev)).T, attributes={'positive': 'down'}) coords_and_dims.append((coord, dim)) # Depth - unbound and bound (mixed). if (len(lbcode) != 5) and \ (lbvc == 2) and \ (np.any(brsvd1 == brlev) and np.any(brsvd1 != brlev)): lower = np.where(brsvd1 == brlev, blev, brsvd1) upper = np.where(brsvd1 == brlev, blev, brlev) coord = _dim_or_aux(blev, standard_name='depth', units='m', bounds=np.vstack((lower, upper)).T, attributes={'positive': 'down'}) coords_and_dims.append((coord, dim)) # Soil level/depth. if len(lbcode) != 5 and lbvc == 6: if np.all(brsvd1 == 0) and np.all(brlev == 0): # UM populates lblev, brsvd1 and brlev metadata INCORRECTLY, # so continue to treat as a soil level. coord = _dim_or_aux(model_level_number, long_name='soil_model_level_number', attributes={'positive': 'down'}) coords_and_dims.append((coord, dim)) elif np.any(brsvd1 != brlev): # UM populates metadata CORRECTLY, # so treat it as the expected (bounded) soil depth. coord = _dim_or_aux(blev, standard_name='depth', units='m', bounds=np.vstack((brsvd1, brlev)).T, attributes={'positive': 'down'}) coords_and_dims.append((coord, dim)) # Pressure. if (lbvc == 8) and \ (len(lbcode) != 5 or (len(lbcode) == 5 and 1 not in [lbcode.ix, lbcode.iy])): coord = _dim_or_aux(blev, long_name='pressure', units='hPa') coords_and_dims.append((coord, dim)) # Air potential temperature. if (len(lbcode) != 5) and \ (lbvc == 19): coord = _dim_or_aux(blev, standard_name='air_potential_temperature', units='K', attributes={'positive': 'up'}) coords_and_dims.append((coord, dim)) # Hybrid pressure levels. if lbvc == 9: model_level_number = _dim_or_aux(model_level_number, standard_name='model_level_number', attributes={'positive': 'up'}) level_pressure = _dim_or_aux(bhlev, long_name='level_pressure', units='Pa', bounds=np.vstack((bhrlev, brsvd2)).T) sigma = AuxCoord(blev, long_name='sigma', bounds=np.vstack((brlev, brsvd1)).T) coords_and_dims.extend([(model_level_number, dim), (level_pressure, dim), (sigma, dim)]) factories.append( Factory(HybridPressureFactory, [{ 'long_name': 'level_pressure' }, { 'long_name': 'sigma' }, Reference('surface_air_pressure')])) # Hybrid height levels. if lbvc == 65: model_level_number = _dim_or_aux(model_level_number, standard_name='model_level_number', attributes={'positive': 'up'}) level_height = _dim_or_aux(blev, long_name='level_height', units='m', bounds=np.vstack((brlev, brsvd1)).T, attributes={'positive': 'up'}) sigma = AuxCoord(bhlev, long_name='sigma', bounds=np.vstack((bhrlev, brsvd2)).T) coords_and_dims.extend([(model_level_number, dim), (level_height, dim), (sigma, dim)]) factories.append( Factory(HybridHeightFactory, [{ 'long_name': 'level_height' }, { 'long_name': 'sigma' }, Reference('orography')])) return coords_and_dims, factories
def grib1_convert(grib): """ Converts a GRIB1 message into the corresponding items of Cube metadata. Args: * grib: A :class:`~iris_grib.GribWrapper` object. Returns: A :class:`iris.fileformats.rules.ConversionMetadata` object. """ if grib.edition != 1: emsg = 'GRIB edition {} is not supported by {!r}.' raise TranslationError(emsg.format(grib.edition, type(grib).__name__)) factories = [] references = [] standard_name = None long_name = None units = None attributes = {} cell_methods = [] dim_coords_and_dims = [] aux_coords_and_dims = [] if \ (grib.gridType=="reduced_gg"): aux_coords_and_dims.append( (AuxCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) aux_coords_and_dims.append( (AuxCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system), 0)) if \ (grib.gridType=="regular_ll") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="regular_ll") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if \ (grib.gridType=="regular_gg") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="regular_gg") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if \ (grib.gridType=="rotated_ll") and \ (grib.jPointsAreConsecutive == 0): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 0)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 1)) if \ (grib.gridType=="rotated_ll") and \ (grib.jPointsAreConsecutive == 1): dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units='degrees', coord_system=grib._coord_system), 1)) dim_coords_and_dims.append((DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord_system=grib._coord_system, circular=grib._x_circular), 0)) if grib.gridType in ["polar_stereographic", "lambert"]: dim_coords_and_dims.append( (DimCoord(grib._y_points, grib._y_coord_name, units="m", coord_system=grib._coord_system), 0)) dim_coords_and_dims.append( (DimCoord(grib._x_points, grib._x_coord_name, units="m", coord_system=grib._coord_system), 1)) if \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 11) and \ (grib._cf_data is None): standard_name = "air_temperature" units = "kelvin" if \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 33) and \ (grib._cf_data is None): standard_name = "x_wind" units = "m s-1" if \ (grib.table2Version < 128) and \ (grib.indicatorOfParameter == 34) and \ (grib._cf_data is None): standard_name = "y_wind" units = "m s-1" if \ (grib._cf_data is not None): standard_name = grib._cf_data.standard_name long_name = grib._cf_data.standard_name or grib._cf_data.long_name units = grib._cf_data.units if \ (grib.table2Version >= 128) and \ (grib._cf_data is None): long_name = "UNKNOWN LOCAL PARAM " + str( grib.indicatorOfParameter) + "." + str(grib.table2Version) units = "???" if \ (grib.table2Version == 1) and \ (grib.indicatorOfParameter >= 128): long_name = "UNKNOWN LOCAL PARAM " + str( grib.indicatorOfParameter) + "." + str(grib.table2Version) units = "???" if \ (grib._phenomenonDateTime != -1.0): aux_coords_and_dims.append( (DimCoord(points=grib.startStep, standard_name='forecast_period', units=grib._forecastTimeUnit), None)) aux_coords_and_dims.append( (DimCoord(points=grib.phenomenon_points('hours'), standard_name='time', units=Unit('hours since epoch', CALENDAR_GREGORIAN)), None)) def add_bounded_time_coords(aux_coords_and_dims, grib): t_bounds = grib.phenomenon_bounds('hours') period = Unit('hours').convert(t_bounds[1] - t_bounds[0], grib._forecastTimeUnit) aux_coords_and_dims.append( (DimCoord(standard_name='forecast_period', units=grib._forecastTimeUnit, points=grib._forecastTime + 0.5 * period, bounds=[grib._forecastTime, grib._forecastTime + period]), None)) aux_coords_and_dims.append( (DimCoord(standard_name='time', units=Unit('hours since epoch', CALENDAR_GREGORIAN), points=0.5 * (t_bounds[0] + t_bounds[1]), bounds=t_bounds), None)) if \ (grib.timeRangeIndicator == 2): add_bounded_time_coords(aux_coords_and_dims, grib) if \ (grib.timeRangeIndicator == 3): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.timeRangeIndicator == 4): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.timeRangeIndicator == 5): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("_difference", coords="time")) if \ (grib.timeRangeIndicator == 51): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.timeRangeIndicator == 113): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.timeRangeIndicator == 114): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.timeRangeIndicator == 115): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.timeRangeIndicator == 116): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.timeRangeIndicator == 117): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.timeRangeIndicator == 118): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("_covariance", coords="time")) if \ (grib.timeRangeIndicator == 123): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("mean", coords="time")) if \ (grib.timeRangeIndicator == 124): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("sum", coords="time")) if \ (grib.timeRangeIndicator == 125): add_bounded_time_coords(aux_coords_and_dims, grib) cell_methods.append(CellMethod("standard_deviation", coords="time")) if \ (grib.levelType == 'pl'): aux_coords_and_dims.append((DimCoord(points=grib.level, long_name="pressure", units="hPa"), None)) if \ (grib.levelType == 'sfc'): if (grib._cf_data is not None) and \ (grib._cf_data.set_height is not None): aux_coords_and_dims.append( (DimCoord(points=grib._cf_data.set_height, long_name="height", units="m", attributes={'positive': 'up'}), None)) elif grib.typeOfLevel == 'heightAboveGround': # required for NCAR aux_coords_and_dims.append((DimCoord(points=grib.level, long_name="height", units="m", attributes={'positive': 'up'}), None)) if \ (grib.levelType == 'ml') and \ (hasattr(grib, 'pv')): aux_coords_and_dims.append( (AuxCoord(grib.level, standard_name='model_level_number', units=1, attributes={'positive': 'up'}), None)) aux_coords_and_dims.append((DimCoord(grib.pv[grib.level], long_name='level_pressure', units='Pa'), None)) aux_coords_and_dims.append((AuxCoord( grib.pv[grib.numberOfCoordinatesValues // 2 + grib.level], long_name='sigma', units=1), None)) factories.append( Factory(HybridPressureFactory, [{ 'long_name': 'level_pressure' }, { 'long_name': 'sigma' }, Reference('surface_pressure')])) if grib._originatingCentre != 'unknown': aux_coords_and_dims.append((AuxCoord(points=grib._originatingCentre, long_name='originating_centre', units='no_unit'), None)) return ConversionMetadata(factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims)
def _convert_scalar_vertical_coords(lbcode, lbvc, blev, lblev, stash, bhlev, bhrlev, brsvd1, brsvd2, brlev): """ Encode scalar vertical level values from PP headers as CM data components. Returns (<list of coords_and_dims>, <list of factories>) """ factories = [] coords_and_dims = [] model_level_number = _model_level_number(lblev) if \ (lbvc == 1) and \ (str(stash) not in STASHCODE_IMPLIED_HEIGHTS) and \ (blev != -1): coords_and_dims.append((DimCoord(blev, standard_name='height', units='m', attributes={'positive': 'up'}), None)) if str(stash) in STASHCODE_IMPLIED_HEIGHTS: coords_and_dims.append((DimCoord(STASHCODE_IMPLIED_HEIGHTS[str(stash)], standard_name='height', units='m', attributes={'positive': 'up'}), None)) if \ (len(lbcode) != 5) and \ (lbvc == 2): coords_and_dims.append((DimCoord(model_level_number, standard_name='model_level_number', attributes={'positive': 'down'}), None)) if \ (len(lbcode) != 5) and \ (lbvc == 2) and \ (brsvd1 == brlev): coords_and_dims.append((DimCoord(blev, standard_name='depth', units='m', attributes={'positive': 'down'}), None)) if \ (len(lbcode) != 5) and \ (lbvc == 2) and \ (brsvd1 != brlev): coords_and_dims.append((DimCoord(blev, standard_name='depth', units='m', bounds=[brsvd1, brlev], attributes={'positive': 'down'}), None)) # Soil level/depth. if len(lbcode) != 5 and lbvc == 6: if brsvd1 == 0 and brlev == 0: # UM populates lblev, brsvd1 and brlev metadata INCORRECTLY, # so continue to treat lblev as a soil level. coord = DimCoord(model_level_number, long_name='soil_model_level_number', attributes={'positive': 'down'}) coords_and_dims.append((coord, None)) elif brsvd1 != brlev: # UM populates metadata CORRECTLY, # so treat it as the expected (bounded) soil depth. coord = DimCoord(blev, standard_name='depth', units='m', bounds=[brsvd1, brlev], attributes={'positive': 'down'}) coords_and_dims.append((coord, None)) if \ (lbvc == 8) and \ (len(lbcode) != 5 or (len(lbcode) == 5 and 1 not in [lbcode.ix, lbcode.iy])): coords_and_dims.append((DimCoord(blev, long_name='pressure', units='hPa'), None)) if \ (len(lbcode) != 5) and \ (lbvc == 19): coords_and_dims.append( (DimCoord(blev, standard_name='air_potential_temperature', units='K', attributes={'positive': 'up'}), None)) # Hybrid pressure levels (--> scalar coordinates) if lbvc == 9: model_level_number = DimCoord(model_level_number, standard_name='model_level_number', attributes={'positive': 'up'}) # The following match the hybrid height scheme, but data has the # blev and bhlev values the other way around. #level_pressure = DimCoord(blev, # long_name='level_pressure', # units='Pa', # bounds=[brlev, brsvd1]) #sigma = AuxCoord(bhlev, # long_name='sigma', # bounds=[bhrlev, brsvd2]) level_pressure = DimCoord(bhlev, long_name='level_pressure', units='Pa', bounds=[bhrlev, brsvd2]) sigma = AuxCoord(blev, long_name='sigma', bounds=[brlev, brsvd1]) coords_and_dims.extend([(model_level_number, None), (level_pressure, None), (sigma, None)]) factories.append( Factory(HybridPressureFactory, [{ 'long_name': 'level_pressure' }, { 'long_name': 'sigma' }, Reference('surface_air_pressure')])) # Hybrid height levels (--> scalar coordinates + factory) if lbvc == 65: coords_and_dims.append((DimCoord(model_level_number, standard_name='model_level_number', attributes={'positive': 'up'}), None)) coords_and_dims.append((DimCoord(blev, long_name='level_height', units='m', bounds=[brlev, brsvd1], attributes={'positive': 'up'}), None)) coords_and_dims.append((AuxCoord(bhlev, long_name='sigma', bounds=[bhrlev, brsvd2]), None)) factories.append( Factory(HybridHeightFactory, [{ 'long_name': 'level_height' }, { 'long_name': 'sigma' }, Reference('orography')])) return coords_and_dims, factories