Пример #1
0
 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,
     )
Пример #2
0
    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)
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
def _all_other_rules(f):
    """
    This deals with all the other rules that have not been factored into any of
    the other convert_scalar_coordinate functions above.

    """
    references = []
    standard_name = None
    long_name = None
    units = None
    attributes = {}
    cell_methods = []
    dim_coords_and_dims = []
    aux_coords_and_dims = []

    # Season coordinates (--> scalar coordinates)
    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))

    # Special case where year is zero and months match.
    # Month coordinates (--> scalar coordinates)
    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])) and f.lbyr == 0
            and f.lbyrd == 0 and f.lbmon == f.lbmond):
        aux_coords_and_dims.append((AuxCoord(f.lbmon,
                                             long_name='month_number'), None))
        aux_coords_and_dims.append((AuxCoord(calendar.month_abbr[f.lbmon],
                                             long_name='month',
                                             units='no_unit'), None))
        aux_coords_and_dims.append((DimCoord(points=f.lbft,
                                             standard_name='forecast_period',
                                             units='hours'), None))

    # "Normal" (i.e. not cross-sectional) lats+lons (--> vector coordinates)
    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))

    # Cross-sectional vertical level types (--> vector coordinates)
    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))

    # Cross-sectional time values (--> vector coordinates)
    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=cf_units.Unit('days since 0000-01-01 00:00:00',
                                          calendar=cf_units.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=cf_units.Unit('days since 0000-01-01 00:00:00',
                                          calendar=cf_units.CALENDAR_360_DAY),
                      bounds=f.x_bounds), 1))

    if (len(f.lbcode) == 5 and f.lbcode[-1] == 3 and f.lbcode.iy == 23
            and f.lbtim.ib == 2 and f.lbtim.ic == 2):
        epoch_days_unit = cf_units.Unit('days since 0000-01-01 00:00:00',
                                        calendar=cf_units.CALENDAR_360_DAY)
        t1_epoch_days = epoch_days_unit.date2num(f.t1)
        t2_epoch_days = epoch_days_unit.date2num(f.t2)
        # The end time is exclusive, not inclusive.
        dim_coords_and_dims.append((DimCoord(np.linspace(t1_epoch_days,
                                                         t2_epoch_days,
                                                         f.lbrow,
                                                         endpoint=False),
                                             standard_name='time',
                                             units=epoch_days_unit,
                                             bounds=f.y_bounds), 0))

    # Site number (--> scalar coordinate)
    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))

    # Site number cross-sections (???)
    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))

    # LBPROC codings (--> cell method + attributes)
    unhandled_lbproc = True
    zone_method = None
    time_method = None
    if f.lbproc == 0:
        unhandled_lbproc = False
    elif f.lbproc == 64:
        zone_method = 'mean'
    elif f.lbproc == 128:
        time_method = 'mean'
    elif f.lbproc == 4096:
        time_method = 'minimum'
    elif f.lbproc == 8192:
        time_method = 'maximum'
    elif f.lbproc == 192:
        time_method = 'mean'
        zone_method = 'mean'

    if time_method is not None:
        if f.lbtim.ia != 0:
            intervals = '{} hour'.format(f.lbtim.ia)
        else:
            intervals = None

        if f.lbtim.ib == 2:
            # Aggregation over a period of time.
            cell_methods.append(
                CellMethod(time_method, coords='time', intervals=intervals))
            unhandled_lbproc = False
        elif f.lbtim.ib == 3 and f.lbproc == 128:
            # Aggregation over a period of time within a year, over a number
            # of years.
            # Only mean (lbproc of 128) is handled as the min/max
            # interpretation is ambiguous e.g. decadal mean of daily max,
            # decadal max of daily mean, decadal mean of max daily mean etc.
            cell_methods.append(
                CellMethod('{} within years'.format(time_method),
                           coords='time',
                           intervals=intervals))
            cell_methods.append(
                CellMethod('{} over years'.format(time_method), coords='time'))
            unhandled_lbproc = False
        else:
            # Generic cell method to indicate a time aggregation.
            cell_methods.append(CellMethod(time_method, coords='time'))
            unhandled_lbproc = False

    if zone_method is not None:
        if f.lbcode == 1:
            cell_methods.append(CellMethod(zone_method, coords='longitude'))
            unhandled_lbproc = False
        elif f.lbcode == 101:
            cell_methods.append(
                CellMethod(zone_method, coords='grid_longitude'))
            unhandled_lbproc = False
        else:
            unhandled_lbproc = True

    if unhandled_lbproc:
        attributes["ukmo__process_flags"] = tuple(
            sorted([
                name for value, name in six.iteritems(
                    iris.fileformats.pp.lbproc_map)
                if isinstance(value, int) and f.lbproc & value
            ]))

    if (f.lbsrce % 10000) == 1111:
        attributes['source'] = 'Data from Met Office Unified Model'
        # Also define MO-netCDF compliant UM version.
        um_major = (f.lbsrce // 10000) // 100
        if um_major != 0:
            um_minor = (f.lbsrce // 10000) % 100
            attributes['um_version'] = '{:d}.{:d}'.format(um_major, um_minor)

    if (f.lbuser[6] != 0 or (f.lbuser[3] // 1000) != 0
            or (f.lbuser[3] % 1000) != 0):
        attributes['STASH'] = f.stash

    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

    # Orography reference field (--> reference target)
    if f.lbuser[3] == 33:
        references.append(ReferenceTarget('orography', None))

    # Surface pressure reference field (--> reference target)
    if f.lbuser[3] == 409 or f.lbuser[3] == 1:
        references.append(ReferenceTarget('surface_air_pressure', None))

    return (references, standard_name, long_name, units, attributes,
            cell_methods, dim_coords_and_dims, aux_coords_and_dims)
Пример #7
0
def _all_other_rules(f):
    """
    This deals with all the other rules that have not been factored into any of
    the other convert_scalar_coordinate functions above.

    """
    references = []
    standard_name = None
    long_name = None
    units = None
    attributes = {}
    cell_methods = []
    dim_coords_and_dims = []
    aux_coords_and_dims = []

    # Season coordinates (--> scalar coordinates)
    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)
        )

    # Special case where year is zero and months match.
    # Month coordinates (--> scalar coordinates)
    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]
            )
        )
        and f.lbyr == 0
        and f.lbyrd == 0
        and f.lbmon == f.lbmond
    ):
        aux_coords_and_dims.append(
            (AuxCoord(f.lbmon, long_name="month_number"), None)
        )
        aux_coords_and_dims.append(
            (
                AuxCoord(
                    calendar.month_abbr[f.lbmon],
                    long_name="month",
                    units="no_unit",
                ),
                None,
            )
        )
        aux_coords_and_dims.append(
            (
                DimCoord(
                    points=f.lbft,
                    standard_name="forecast_period",
                    units="hours",
                ),
                None,
            )
        )

    # "Normal" (i.e. not cross-sectional) lats+lons (--> vector coordinates)
    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,
            )
        )

    # Cross-sectional vertical level types (--> vector coordinates)
    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,
            )
        )

    # Cross-sectional time values (--> vector coordinates)
    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=cf_units.Unit(
                        "days since 0000-01-01 00:00:00",
                        calendar=cf_units.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=cf_units.Unit(
                        "days since 0000-01-01 00:00:00",
                        calendar=cf_units.CALENDAR_360_DAY,
                    ),
                    bounds=f.x_bounds,
                ),
                1,
            )
        )

    if (
        len(f.lbcode) == 5
        and f.lbcode[-1] == 3
        and f.lbcode.iy == 23
        and f.lbtim.ib == 2
        and f.lbtim.ic == 2
    ):
        epoch_days_unit = cf_units.Unit(
            "days since 0000-01-01 00:00:00",
            calendar=cf_units.CALENDAR_360_DAY,
        )
        t1_epoch_days = epoch_days_unit.date2num(f.t1)
        t2_epoch_days = epoch_days_unit.date2num(f.t2)
        # The end time is exclusive, not inclusive.
        dim_coords_and_dims.append(
            (
                DimCoord(
                    np.linspace(
                        t1_epoch_days, t2_epoch_days, f.lbrow, endpoint=False
                    ),
                    standard_name="time",
                    units=epoch_days_unit,
                    bounds=f.y_bounds,
                ),
                0,
            )
        )

    # Site number (--> scalar coordinate)
    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,
            )
        )

    # Site number cross-sections (???)
    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.0e30)
        and all(f.upper_x_domain != -1.0e30)
    ):
        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.0e30)
        and all(f.upper_y_domain != -1.0e30)
    ):
        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,
            )
        )

    # LBPROC codings (--> cell method + attributes)
    unhandled_lbproc = True
    zone_method = None
    time_method = None
    if f.lbproc == 0:
        unhandled_lbproc = False
    elif f.lbproc == 64:
        zone_method = "mean"
    elif f.lbproc == 128:
        time_method = "mean"
    elif f.lbproc == 4096:
        time_method = "minimum"
    elif f.lbproc == 8192:
        time_method = "maximum"
    elif f.lbproc == 192:
        time_method = "mean"
        zone_method = "mean"

    if time_method is not None:
        if f.lbtim.ia != 0:
            intervals = "{} hour".format(f.lbtim.ia)
        else:
            intervals = None

        if f.lbtim.ib == 2:
            # Aggregation over a period of time.
            cell_methods.append(
                CellMethod(time_method, coords="time", intervals=intervals)
            )
            unhandled_lbproc = False
        elif f.lbtim.ib == 3 and f.lbproc == 128:
            # Aggregation over a period of time within a year, over a number
            # of years.
            # Only mean (lbproc of 128) is handled as the min/max
            # interpretation is ambiguous e.g. decadal mean of daily max,
            # decadal max of daily mean, decadal mean of max daily mean etc.
            cell_methods.append(
                CellMethod(
                    "{} within years".format(time_method),
                    coords="time",
                    intervals=intervals,
                )
            )
            cell_methods.append(
                CellMethod("{} over years".format(time_method), coords="time")
            )
            unhandled_lbproc = False
        else:
            # Generic cell method to indicate a time aggregation.
            cell_methods.append(CellMethod(time_method, coords="time"))
            unhandled_lbproc = False

    if zone_method is not None:
        if f.lbcode == 1:
            cell_methods.append(CellMethod(zone_method, coords="longitude"))
            for coord, _dim in dim_coords_and_dims:
                if coord.standard_name == "longitude":
                    if len(coord.points) == 1:
                        coord.bounds = np.array([0.0, 360.0], dtype=np.float32)
                    else:
                        coord.guess_bounds()
            unhandled_lbproc = False
        elif f.lbcode == 101:
            cell_methods.append(
                CellMethod(zone_method, coords="grid_longitude")
            )
            for coord, _dim in dim_coords_and_dims:
                if coord.standard_name == "grid_longitude":
                    if len(coord.points) == 1:
                        coord.bounds = np.array([0.0, 360.0], dtype=np.float32)
                    else:
                        coord.guess_bounds()
            unhandled_lbproc = False
        else:
            unhandled_lbproc = True

    if unhandled_lbproc:
        attributes["ukmo__process_flags"] = tuple(
            sorted(
                [
                    name
                    for value, name in LBPROC_MAP.items()
                    if isinstance(value, int) and f.lbproc & value
                ]
            )
        )

    if (f.lbsrce % 10000) == 1111:
        attributes["source"] = "Data from Met Office Unified Model"
        # Also define MO-netCDF compliant UM version.
        um_major = (f.lbsrce // 10000) // 100
        if um_major != 0:
            um_minor = (f.lbsrce // 10000) % 100
            attributes["um_version"] = "{:d}.{:d}".format(um_major, um_minor)

    if (
        f.lbuser[6] != 0
        or (f.lbuser[3] // 1000) != 0
        or (f.lbuser[3] % 1000) != 0
    ):
        attributes["STASH"] = f.stash

    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

    # Orography reference field (--> reference target)
    if f.lbuser[3] == 33:
        references.append(ReferenceTarget("orography", None))

    # Surface pressure reference field (--> reference target)
    if f.lbuser[3] == 409 or f.lbuser[3] == 1:
        references.append(ReferenceTarget("surface_air_pressure", None))

    return (
        references,
        standard_name,
        long_name,
        units,
        attributes,
        cell_methods,
        dim_coords_and_dims,
        aux_coords_and_dims,
    )