Example #1
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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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=np.mean(grib.phenomenon_bounds('hours')),
                      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 == 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)
Example #2
0
def _convert_vertical_coords(lbcode,
                             lbvc,
                             blev,
                             lblev,
                             stash,
                             bhlev,
                             bhrlev,
                             brsvd1,
                             brsvd2,
                             brlev,
                             dim=None):
    """
    Encode scalar or vector vertical level values from PP headers as CM data
    components.

    Args:

    * lbcode:
        Scalar field :class:`iris.fileformats.pp.SplittableInt` value.

    * lbvc:
        Scalar field value.

    * blev:
        Scalar field value or :class:`numpy.ndarray` vector of field values.

    * lblev:
        Scalar field value or :class:`numpy.ndarray` vector of field values.

    * stash:
        Scalar field :class:`iris.fileformats.pp.STASH` value.

    * bhlev:
        Scalar field value or :class:`numpy.ndarray` vector of field values.

    * bhrlev:
        Scalar field value or :class:`numpy.ndarray` vector of field values.

    * brsvd1:
        Scalar field value or :class:`numpy.ndarray` vector of field values.

    * brsvd2:
        Scalar field value or :class:`numpy.ndarray` vector of field values.

    * brlev:
        Scalar field value or :class:`numpy.ndarray` vector of field values.

    Kwargs:

    * dim:
        Associated dimension of the vertical coordinate. Defaults to None.

    Returns:
        A tuple containing a list of coords_and_dims, and a list of factories.

    """
    factories = []
    coords_and_dims = []

    # See Word no. 33 (LBLEV) in section 4 of UM Model Docs (F3).
    BASE_RHO_LEVEL_LBLEV = 9999
    model_level_number = np.atleast_1d(lblev)
    model_level_number[model_level_number == BASE_RHO_LEVEL_LBLEV] = 0

    # Ensure to vectorise these arguments as arrays, as they participate
    # in the conditions of convert rules.
    blev = np.atleast_1d(blev)
    brsvd1 = np.atleast_1d(brsvd1)
    brlev = np.atleast_1d(brlev)

    # Height.
    if (lbvc == 1) and \
            str(stash) not in STASHCODE_IMPLIED_HEIGHTS and \
            np.all(blev != -1):
        coord = _dim_or_aux(blev,
                            standard_name='height',
                            units='m',
                            attributes={'positive': 'up'})
        coords_and_dims.append((coord, dim))

    if str(stash) in STASHCODE_IMPLIED_HEIGHTS:
        height = STASHCODE_IMPLIED_HEIGHTS[str(stash)]
        coord = DimCoord(height,
                         standard_name='height',
                         units='m',
                         attributes={'positive': 'up'})
        coords_and_dims.append((coord, None))

    # Model level number.
    if (len(lbcode) != 5) and \
            (lbvc == 2):
        coord = _dim_or_aux(model_level_number,
                            standard_name='model_level_number',
                            attributes={'positive': 'down'})
        coords_and_dims.append((coord, dim))

    # Depth - unbound.
    if (len(lbcode) != 5) and \
            (lbvc == 2) and \
            np.all(brsvd1 == brlev):
        coord = _dim_or_aux(blev,
                            standard_name='depth',
                            units='m',
                            attributes={'positive': 'down'})
        coords_and_dims.append((coord, dim))

    # Depth - bound.
    if (len(lbcode) != 5) and \
            (lbvc == 2) and \
            np.all(brsvd1 != brlev):
        coord = _dim_or_aux(blev,
                            standard_name='depth',
                            units='m',
                            bounds=np.vstack((brsvd1, brlev)).T,
                            attributes={'positive': 'down'})
        coords_and_dims.append((coord, dim))

    # Depth - unbound and bound (mixed).
    if (len(lbcode) != 5) and \
            (lbvc == 2) and \
            (np.any(brsvd1 == brlev) and np.any(brsvd1 != brlev)):
        lower = np.where(brsvd1 == brlev, blev, brsvd1)
        upper = np.where(brsvd1 == brlev, blev, brlev)
        coord = _dim_or_aux(blev,
                            standard_name='depth',
                            units='m',
                            bounds=np.vstack((lower, upper)).T,
                            attributes={'positive': 'down'})
        coords_and_dims.append((coord, dim))

    # Soil level/depth.
    if len(lbcode) != 5 and lbvc == 6:
        if np.all(brsvd1 == 0) and np.all(brlev == 0):
            # UM populates lblev, brsvd1 and brlev metadata INCORRECTLY,
            # so continue to treat as a soil level.
            coord = _dim_or_aux(model_level_number,
                                long_name='soil_model_level_number',
                                attributes={'positive': 'down'})
            coords_and_dims.append((coord, dim))
        elif np.any(brsvd1 != brlev):
            # UM populates metadata CORRECTLY,
            # so treat it as the expected (bounded) soil depth.
            coord = _dim_or_aux(blev,
                                standard_name='depth',
                                units='m',
                                bounds=np.vstack((brsvd1, brlev)).T,
                                attributes={'positive': 'down'})
            coords_and_dims.append((coord, dim))

    # Pressure.
    if (lbvc == 8) and \
            (len(lbcode) != 5 or (len(lbcode) == 5 and
                                  1 not in [lbcode.ix, lbcode.iy])):
        coord = _dim_or_aux(blev, long_name='pressure', units='hPa')
        coords_and_dims.append((coord, dim))

    # Air potential temperature.
    if (len(lbcode) != 5) and \
            (lbvc == 19):
        coord = _dim_or_aux(blev,
                            standard_name='air_potential_temperature',
                            units='K',
                            attributes={'positive': 'up'})
        coords_and_dims.append((coord, dim))

    # Hybrid pressure levels.
    if lbvc == 9:
        model_level_number = _dim_or_aux(model_level_number,
                                         standard_name='model_level_number',
                                         attributes={'positive': 'up'})
        level_pressure = _dim_or_aux(bhlev,
                                     long_name='level_pressure',
                                     units='Pa',
                                     bounds=np.vstack((bhrlev, brsvd2)).T)
        sigma = AuxCoord(blev,
                         long_name='sigma',
                         bounds=np.vstack((brlev, brsvd1)).T)
        coords_and_dims.extend([(model_level_number, dim),
                                (level_pressure, dim), (sigma, dim)])
        factories.append(
            Factory(HybridPressureFactory,
                    [{
                        'long_name': 'level_pressure'
                    }, {
                        'long_name': 'sigma'
                    },
                     Reference('surface_air_pressure')]))

    # Hybrid height levels.
    if lbvc == 65:
        model_level_number = _dim_or_aux(model_level_number,
                                         standard_name='model_level_number',
                                         attributes={'positive': 'up'})
        level_height = _dim_or_aux(blev,
                                   long_name='level_height',
                                   units='m',
                                   bounds=np.vstack((brlev, brsvd1)).T,
                                   attributes={'positive': 'up'})
        sigma = AuxCoord(bhlev,
                         long_name='sigma',
                         bounds=np.vstack((bhrlev, brsvd2)).T)
        coords_and_dims.extend([(model_level_number, dim), (level_height, dim),
                                (sigma, dim)])
        factories.append(
            Factory(HybridHeightFactory, [{
                'long_name': 'level_height'
            }, {
                'long_name': 'sigma'
            },
                                          Reference('orography')]))

    return coords_and_dims, factories
Example #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 in [0, 1]):
        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, 11)):
        add_bounded_time_coords(aux_coords_and_dims, grib)

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (1, 11)) and \
            (grib.perturbationNumber is not None):
        cell_methods.append(
            CellMethod('realization',
                       coords=('realization', ),
                       intervals=('1', ),
                       comments=(' ENS', )))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 0):
        cell_methods.append(CellMethod("mean", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 1):
        cell_methods.append(CellMethod("sum", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 2):
        cell_methods.append(CellMethod("maximum", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 3):
        cell_methods.append(CellMethod("minimum", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 4):
        cell_methods.append(CellMethod("_difference", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 5):
        cell_methods.append(CellMethod("_root_mean_square", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 6):
        cell_methods.append(CellMethod("standard_deviation", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 7):
        cell_methods.append(CellMethod("_convariance", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) and \
            (grib.typeOfStatisticalProcessing == 8):
        cell_methods.append(CellMethod("_difference", coords="time"))

    if \
            (grib.edition == 2) and \
            (grib.productDefinitionTemplateNumber in (8, 11)) 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))

    # required for NCMRWF
    if \
            (grib.edition == 2) and \
            (grib.typeOfFirstFixedSurface == 106) 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="depth",
            long_name="depth_below_land_surface",
            units="m",
            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 in [1, 11]):
        aux_coords_and_dims.append((DimCoord(points=grib.perturbationNumber,
                                             standard_name='realization',
                                             long_name='ensemble_member',
                                             units='no_unit'), None))

    if \
            (grib.edition == 2) and \
            grib.productDefinitionTemplateNumber not in (0, 1, 8, 11):
        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)
Example #4
0
def _convert_scalar_vertical_coords(lbcode, lbvc, blev, lblev, stash,
                                    bhlev, bhrlev, brsvd1, brsvd2, brlev):
    """
    Encode scalar vertical level values from PP headers as CM data components.

    Returns (<list of coords_and_dims>, <list of factories>)

    """
    factories = []
    coords_and_dims = []
    model_level_number = _model_level_number(lblev)

    if \
            (lbvc == 1) and \
            (str(stash) not in STASHCODE_IMPLIED_HEIGHTS) and \
            (blev != -1):
        coords_and_dims.append(
            (DimCoord(blev, standard_name='height', units='m',
                      attributes={'positive': 'up'}),
             None))

    if str(stash) in STASHCODE_IMPLIED_HEIGHTS:
        coords_and_dims.append(
            (DimCoord(STASHCODE_IMPLIED_HEIGHTS[str(stash)],
                      standard_name='height', units='m',
                      attributes={'positive': 'up'}),
             None))

    if \
            (len(lbcode) != 5) and \
            (lbvc == 2):
        coords_and_dims.append((DimCoord(model_level_number, standard_name='model_level_number', attributes={'positive': 'down'}), None))

    if \
            (len(lbcode) != 5) and \
            (lbvc == 2) and \
            (brsvd1 == brlev):
        coords_and_dims.append((DimCoord(blev, standard_name='depth', units='m', attributes={'positive': 'down'}), None))

    if \
            (len(lbcode) != 5) and \
            (lbvc == 2) and \
            (brsvd1 != brlev):
        coords_and_dims.append((DimCoord(blev, standard_name='depth', units='m', bounds=[brsvd1, brlev], attributes={'positive': 'down'}), None))

    # soil level
    if len(lbcode) != 5 and lbvc == 6:
        coords_and_dims.append((DimCoord(model_level_number, long_name='soil_model_level_number', attributes={'positive': 'down'}), None))

    if \
            (lbvc == 8) and \
            (len(lbcode) != 5 or (len(lbcode) == 5 and 1 not in [lbcode.ix, lbcode.iy])):
        coords_and_dims.append((DimCoord(blev, long_name='pressure', units='hPa'), None))

    if \
            (len(lbcode) != 5) and \
            (lbvc == 19):
        coords_and_dims.append((DimCoord(blev, standard_name='air_potential_temperature', units='K', attributes={'positive': 'up'}), None))

    # Hybrid pressure levels (--> scalar coordinates)
    if lbvc == 9:
        model_level_number = DimCoord(model_level_number,
                                      standard_name='model_level_number',
                                      attributes={'positive': 'up'})
        # The following match the hybrid height scheme, but data has the
        # blev and bhlev values the other way around.
        #level_pressure = DimCoord(blev,
        #                          long_name='level_pressure',
        #                          units='Pa',
        #                          bounds=[brlev, brsvd1])
        #sigma = AuxCoord(bhlev,
        #                 long_name='sigma',
        #                 bounds=[bhrlev, brsvd2])
        level_pressure = DimCoord(bhlev,
                                  long_name='level_pressure',
                                  units='Pa',
                                  bounds=[bhrlev, brsvd2])
        sigma = AuxCoord(blev,
                         long_name='sigma',
                         bounds=[brlev, brsvd1])
        coords_and_dims.extend([(model_level_number, None),
                                    (level_pressure, None),
                                    (sigma, None)])
        factories.append(Factory(HybridPressureFactory,
                                 [{'long_name': 'level_pressure'},
                                  {'long_name': 'sigma'},
                                  Reference('surface_air_pressure')]))

    # Hybrid height levels (--> scalar coordinates + factory)
    if lbvc == 65:
        coords_and_dims.append((DimCoord(model_level_number, standard_name='model_level_number', attributes={'positive': 'up'}), None))
        coords_and_dims.append((DimCoord(blev, long_name='level_height', units='m', bounds=[brlev, brsvd1], attributes={'positive': 'up'}), None))
        coords_and_dims.append((AuxCoord(bhlev, long_name='sigma', bounds=[bhrlev, brsvd2]), None))
        factories.append(Factory(HybridHeightFactory, [{'long_name': 'level_height'}, {'long_name': 'sigma'}, Reference('orography')]))

    return coords_and_dims, factories