def test_hourly_mean(self):
     # lbtim.ia = 1 -> hourly
     field = mock.MagicMock(lbproc=128,
                            lbtim=mock.Mock(ia=1, ib=2, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('mean', 'time', '1 hour')]
     self.assertEqual(res, expected)
 def test_other_lbtim_ib(self):
     # lbtim.ib = 5 -> non-specific aggregation
     field = mock.MagicMock(lbproc=4096,
                            lbtim=mock.Mock(ia=24, ib=5, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('minimum', 'time')]
     self.assertEqual(res, expected)
    def test_lbcode3x23(self):
        time_bounds = np.array([[0.875, 1.125], [1.125, 1.375],
                                [1.375, 1.625], [1.625, 1.875]])
        field = mock.MagicMock(
            lbproc=0, bzx=0, bdx=0, lbnpt=3, lbrow=4,
            t1=nc_datetime(2000, 1, 2, hour=0, minute=0, second=0),
            t2=nc_datetime(2000, 1, 3, hour=0, minute=0, second=0),
            lbtim=mock.Mock(ia=1, ib=2, ic=2),
            lbcode=SplittableInt(31323, {'iy': slice(0, 2),
                                         'ix': slice(2, 4)}),
            x_bounds=None,
            y_bounds=time_bounds,
            _x_coord_name=lambda: 'longitude',
            _y_coord_name=lambda: 'latitude')

        spec = ['lbtim', 'lbcode', 'lbrow', 'lbnpt', 'lbproc', 'lbsrce',
                'lbuser', 'bzx', 'bdx', 'bdy', 'bmdi', 't1', 't2', 'stash',
                'x_bounds', 'y_bounds', '_x_coord_name', '_y_coord_name']
        field.mock_add_spec(spec)
        res = _all_other_rules(field)[DIM_COORDS_INDEX]

        expected_time_points = np.array([1, 1.25, 1.5, 1.75]) + (2000 * 360)
        expected_unit = Unit('days since 0000-01-01 00:00:00',
                             calendar=CALENDAR_360_DAY)
        expected = [(DimCoord(expected_time_points, standard_name='time',
                              units=expected_unit, bounds=time_bounds), 0)]
        self.assertCoordsAndDimsListsMatch(res, expected)
 def test_daily_min(self):
     # lbproc = 4096 -> min
     field = mock.MagicMock(lbproc=4096,
                            lbtim=mock.Mock(ia=24, ib=2, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('minimum', 'time', '24 hour')]
     self.assertEqual(res, expected)
 def test_hourly_mean_over_multiple_years(self):
     field = mock.MagicMock(lbproc=128,
                            lbtim=mock.Mock(ia=1, ib=3, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('mean within years', 'time', '1 hour'),
                 CellMethod('mean over years', 'time')]
     self.assertEqual(res, expected)
 def test_time_mean(self):
     # lbproc = 128 -> mean
     # lbtim.ib = 2 -> simple t1 to t2 interval.
     field = mock.MagicMock(lbproc=128,
                            lbtim=mock.Mock(ia=0, ib=2, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('mean', 'time')]
     self.assertEqual(res, expected)
 def test_time_mean_over_multiple_years(self):
     # lbtim.ib = 3 -> interval within a year, over multiple years.
     field = mock.MagicMock(lbproc=128,
                            lbtim=mock.Mock(ia=0, ib=3, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('mean within years', 'time'),
                 CellMethod('mean over years', 'time')]
     self.assertEqual(res, expected)
 def test_multiple_unordered_rotated_lbprocs(self):
     field = mock.MagicMock(lbproc=192, bzx=0, bdx=1, lbnpt=3, lbrow=3,
                            lbtim=mock.Mock(ia=24, ib=5, ic=3),
                            lbcode=SplittableInt(101), x_bounds=None,
                            _x_coord_name=lambda: 'grid_longitude',
                            _y_coord_name=lambda: 'grid_latitude')
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('mean', 'time'),
                 CellMethod('mean', 'grid_longitude')]
     self.assertEqual(res, expected)
示例#9
0
 def test_multiple_unordered_lbprocs(self):
     field = mock.MagicMock(lbproc=192,
                            lbtim=mock.Mock(ia=24, ib=5, ic=3),
                            lbcode=SplittableInt(1),
                            _x_coord_name=lambda: 'longitude',
                            _y_coord_name=lambda: 'latitude')
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('mean', 'time'),
                 CellMethod('mean', 'longitude')]
     self.assertEqual(res, expected)
示例#10
0
    def test_month_coord(self):
        field = self._make_field()
        field.mock_add_spec(self._spec)
        res = _all_other_rules(field)[AUX_COORDS_INDEX]

        expected = [(AuxCoord(3, long_name='month_number'), None),
                    (AuxCoord('Mar', long_name='month',
                     units=Unit('no unit')), None),
                    (DimCoord(points=0, standard_name='forecast_period',
                     units=Unit('hours')), None)]
        self.assertCoordsAndDimsListsMatch(res, expected)
示例#11
0
    def test_nonzero_yeard(self):
        field = self._make_field(lbyrd=1)
        field.mock_add_spec(self._spec)
        res = _all_other_rules(field)[AUX_COORDS_INDEX]

        self.assertCoordsAndDimsListsMatch(res, [])
示例#12
0
 def test_climatology_max(self):
     field = mock.MagicMock(lbproc=4096, lbtim=mock.Mock(ia=24, ib=3, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('minimum', 'time')]
     self.assertEqual(res, expected)
示例#13
0
 def test_custom_max(self):
     field = mock.MagicMock(lbproc=8192,
                            lbtim=mock.Mock(ia=47, ib=2, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('maximum', 'time', '47 hour')]
     self.assertEqual(res, expected)
示例#14
0
def _convert_collation(collation):
    """
    Converts a FieldCollation into the corresponding items of Cube
    metadata.

    Args:

    * collation:
        A FieldCollation object.

    Returns:
        A :class:`iris.fileformats.rules.ConversionMetadata` object.

    .. note:
        This is the 'loader.converter', in the control structure passed to the
        generic rules code, :meth:`iris.fileformats.rules.load_cubes`.

    """
    from iris.fileformats.rules import ConversionMetadata
    from iris.fileformats.pp_rules import (_convert_time_coords,
                                           _convert_vertical_coords,
                                           _convert_scalar_realization_coords,
                                           _convert_scalar_pseudo_level_coords,
                                           _all_other_rules)

    # For all the scalar conversions, all fields in the collation will
    # give the same result, so the choice is arbitrary.
    field = collation.fields[0]

    # Call "all other" rules.
    (references, standard_name, long_name, units, attributes, cell_methods,
     dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field)

    # Adjust any dimension bindings to account for the extra leading
    # dimensions added by the collation.
    if collation.vector_dims_shape:

        def _adjust_dims(coords_and_dims, n_dims):
            def adjust(dims):
                if dims is not None:
                    dims += n_dims
                return dims

            return [(coord, adjust(dims)) for coord, dims in coords_and_dims]

        n_collation_dims = len(collation.vector_dims_shape)
        dim_coords_and_dims = _adjust_dims(dim_coords_and_dims,
                                           n_collation_dims)
        aux_coords_and_dims = _adjust_dims(aux_coords_and_dims,
                                           n_collation_dims)

    # Dimensions to which we've already assigned dimension coordinates.
    dim_coord_dims = set()

    # Helper call to choose which coords are dimensions and which auxiliary.
    def _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                     aux_coords_and_dims):
        def key_func(item):
            return _HINTS.get(item[0].name(), len(_HINTS))

        # Target the first DimCoord for a dimension at dim_coords,
        # and target everything else at aux_coords.
        for coord, dims in sorted(coords_and_dims, key=key_func):
            if (isinstance(coord, DimCoord) and dims is not None
                    and len(dims) == 1 and dims[0] not in dim_coord_dims):
                dim_coords_and_dims.append((coord, dims))
                dim_coord_dims.add(dims[0])
            else:
                aux_coords_and_dims.append((coord, dims))

    # Call "time" rules.
    #
    # For "normal" (non-cross-sectional) time values.
    vector_headers = collation.element_arrays_and_dims
    # If the collation doesn't define a vector of values for a
    # particular header then it must be constant over all fields in the
    # collation. In which case it's safe to get the value from any field.
    t1, t1_dims = vector_headers.get('t1', (field.t1, ()))
    t2, t2_dims = vector_headers.get('t2', (field.t2, ()))
    lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ()))
    coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim,
                                           field.time_unit('hours'), t1, t2,
                                           lbft, t1_dims, t2_dims, lbft_dims)
    # Bind resulting coordinates to dimensions, where suitable.
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # Call "vertical" rules.
    #
    # "Normal" (non-cross-sectional) vertical levels
    blev, blev_dims = vector_headers.get('blev', (field.blev, ()))
    lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ()))
    bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ()))
    bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ()))
    brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ()))
    brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ()))
    brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ()))
    # Find all the non-trivial dimension values
    dims = set(
        filter(None, [
            blev_dims, lblev_dims, bhlev_dims, bhrlev_dims, brsvd1_dims,
            brsvd2_dims, brlev_dims
        ]))
    if len(dims) > 1:
        raise TranslationError('Unsupported multiple values for vertical '
                               'dimension.')
    if dims:
        v_dims = dims.pop()
        if len(v_dims) > 1:
            raise TranslationError('Unsupported multi-dimension vertical '
                                   'headers.')
    else:
        v_dims = ()
    coords_and_dims, factories = _convert_vertical_coords(
        field.lbcode, field.lbvc, blev, lblev, field.stash, bhlev, bhrlev,
        brsvd1, brsvd2, brlev, v_dims)
    # Bind resulting coordinates to dimensions, where suitable.
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # Realization (aka ensemble) (--> scalar coordinates)
    aux_coords_and_dims.extend(
        _convert_scalar_realization_coords(lbrsvd4=field.lbrsvd[3]))

    # Pseudo-level coordinate (--> scalar coordinates)
    aux_coords_and_dims.extend(
        _convert_scalar_pseudo_level_coords(lbuser5=field.lbuser[4]))

    return ConversionMetadata(factories, references, standard_name, long_name,
                              units, attributes, cell_methods,
                              dim_coords_and_dims, aux_coords_and_dims)
def _convert_collation(collation):
    """
    Converts a FieldCollation into the corresponding items of Cube
    metadata.

    Args:

    * collation:
        A FieldCollation object.

    Returns:
        A :class:`iris.fileformats.rules.ConversionMetadata` object.

    """
    # For all the scalar conversions all fields in the collation will
    # give the same result, so the choice is arbitrary.
    field = collation.fields[0]

    # All the "other" rules.
    (references, standard_name, long_name, units, attributes, cell_methods,
     dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field)

    # Adjust any dimension bindings to account for the extra leading
    # dimensions added by the collation.
    if collation.vector_dims_shape:
        n_collation_dims = len(collation.vector_dims_shape)
        dim_coords_and_dims = _adjust_dims(dim_coords_and_dims,
                                           n_collation_dims)
        aux_coords_and_dims = _adjust_dims(aux_coords_and_dims,
                                           n_collation_dims)

    # "Normal" (non-cross-sectional) time values
    vector_headers = collation.element_arrays_and_dims
    # If the collation doesn't define a vector of values for a
    # particular header then it must be constant over all fields in the
    # collation. In which case it's safe to get the value from any field.
    t1, t1_dims = vector_headers.get('t1', (field.t1, ()))
    t2, t2_dims = vector_headers.get('t2', (field.t2, ()))
    lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ()))
    coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim,
                                           field.time_unit('hours'), t1, t2,
                                           lbft, t1_dims, t2_dims, lbft_dims)
    dim_coord_dims = set()
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # "Normal" (non-cross-sectional) vertical levels
    blev, blev_dims = vector_headers.get('blev', (field.blev, ()))
    lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ()))
    bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ()))
    bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ()))
    brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ()))
    brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ()))
    brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ()))
    # Find all the non-trivial dimension values
    dims = set(
        filter(None, [
            blev_dims, lblev_dims, bhlev_dims, bhrlev_dims, brsvd1_dims,
            brsvd2_dims, brlev_dims
        ]))
    if len(dims) > 1:
        raise TranslationError('Unsupported multiple values for vertical '
                               'dimension.')
    if dims:
        v_dims = dims.pop()
        if len(v_dims) > 1:
            raise TranslationError('Unsupported multi-dimension vertical '
                                   'headers.')
    else:
        v_dims = ()
    coords_and_dims, factories = _convert_vertical_coords(
        field.lbcode, field.lbvc, blev, lblev, field.stash, bhlev, bhrlev,
        brsvd1, brsvd2, brlev, v_dims)
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # Realization (aka ensemble) (--> scalar coordinates)
    aux_coords_and_dims.extend(
        _convert_scalar_realization_coords(lbrsvd4=field.lbrsvd[3]))

    # Pseudo-level coordinate (--> scalar coordinates)
    aux_coords_and_dims.extend(
        _convert_scalar_pseudo_level_coords(lbuser5=field.lbuser[4]))

    return ConversionMetadata(factories, references, standard_name, long_name,
                              units, attributes, cell_methods,
                              dim_coords_and_dims, aux_coords_and_dims)
示例#16
0
文件: _fast_load.py 项目: rcomer/iris
def _convert_collation(collation):
    """
    Converts a FieldCollation into the corresponding items of Cube
    metadata.

    Args:

    * collation:
        A FieldCollation object.

    Returns:
        A :class:`iris.fileformats.rules.ConversionMetadata` object.

    .. note:
        This is the 'loader.converter', in the control structure passed to the
        generic rules code, :meth:`iris.fileformats.rules.load_cubes`.

    """
    from iris.fileformats.rules import ConversionMetadata
    from iris.fileformats.pp_rules import (_convert_time_coords,
                                           _convert_vertical_coords,
                                           _convert_scalar_realization_coords,
                                           _convert_scalar_pseudo_level_coords,
                                           _all_other_rules)

    # For all the scalar conversions, all fields in the collation will
    # give the same result, so the choice is arbitrary.
    field = collation.fields[0]

    # Call "all other" rules.
    (references, standard_name, long_name, units, attributes, cell_methods,
     dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field)

    # Adjust any dimension bindings to account for the extra leading
    # dimensions added by the collation.
    if collation.vector_dims_shape:
        def _adjust_dims(coords_and_dims, n_dims):
            def adjust(dims):
                if dims is not None:
                    dims += n_dims
                return dims
            return [(coord, adjust(dims)) for coord, dims in coords_and_dims]

        n_collation_dims = len(collation.vector_dims_shape)
        dim_coords_and_dims = _adjust_dims(dim_coords_and_dims,
                                           n_collation_dims)
        aux_coords_and_dims = _adjust_dims(aux_coords_and_dims,
                                           n_collation_dims)

    # Dimensions to which we've already assigned dimension coordinates.
    dim_coord_dims = set()

    # Helper call to choose which coords are dimensions and which auxiliary.
    def _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                     aux_coords_and_dims):
        def key_func(item):
            return _HINTS.get(item[0].name(), len(_HINTS))
        # Target the first DimCoord for a dimension at dim_coords,
        # and target everything else at aux_coords.
        for coord, dims in sorted(coords_and_dims, key=key_func):
            if (isinstance(coord, DimCoord) and dims is not None and
                    len(dims) == 1 and dims[0] not in dim_coord_dims):
                dim_coords_and_dims.append((coord, dims))
                dim_coord_dims.add(dims[0])
            else:
                aux_coords_and_dims.append((coord, dims))

    # Call "time" rules.
    #
    # For "normal" (non-cross-sectional) time values.
    vector_headers = collation.element_arrays_and_dims
    # If the collation doesn't define a vector of values for a
    # particular header then it must be constant over all fields in the
    # collation. In which case it's safe to get the value from any field.
    t1, t1_dims = vector_headers.get('t1', (field.t1, ()))
    t2, t2_dims = vector_headers.get('t2', (field.t2, ()))
    lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ()))
    coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim,
                                           field.time_unit('hours'),
                                           t1, t2, lbft,
                                           t1_dims, t2_dims, lbft_dims)
    # Bind resulting coordinates to dimensions, where suitable.
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # Call "vertical" rules.
    #
    # "Normal" (non-cross-sectional) vertical levels
    blev, blev_dims = vector_headers.get('blev', (field.blev, ()))
    lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ()))
    bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ()))
    bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ()))
    brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ()))
    brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ()))
    brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ()))
    # Find all the non-trivial dimension values
    dims = set(filter(None, [blev_dims, lblev_dims, bhlev_dims, bhrlev_dims,
                             brsvd1_dims, brsvd2_dims, brlev_dims]))
    if len(dims) > 1:
        raise TranslationError('Unsupported multiple values for vertical '
                               'dimension.')
    if dims:
        v_dims = dims.pop()
        if len(v_dims) > 1:
            raise TranslationError('Unsupported multi-dimension vertical '
                                   'headers.')
    else:
        v_dims = ()
    coords_and_dims, factories = _convert_vertical_coords(field.lbcode,
                                                          field.lbvc,
                                                          blev, lblev,
                                                          field.stash,
                                                          bhlev, bhrlev,
                                                          brsvd1, brsvd2,
                                                          brlev, v_dims)
    # Bind resulting coordinates to dimensions, where suitable.
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # Realization (aka ensemble) (--> scalar coordinates)
    aux_coords_and_dims.extend(_convert_scalar_realization_coords(
        lbrsvd4=field.lbrsvd[3]))

    # Pseudo-level coordinate (--> scalar coordinates)
    aux_coords_and_dims.extend(_convert_scalar_pseudo_level_coords(
        lbuser5=field.lbuser[4]))

    return ConversionMetadata(factories, references, standard_name, long_name,
                              units, attributes, cell_methods,
                              dim_coords_and_dims, aux_coords_and_dims)
示例#17
0
 def test_other_lbtim_ib(self):
     # lbtim.ib = 5 -> non-specific aggregation
     field = mock.MagicMock(lbproc=4096, lbtim=mock.Mock(ia=24, ib=5, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('minimum', 'time')]
     self.assertEqual(res, expected)
示例#18
0
def _convert_collation(collation):
    """
    Converts a FieldCollation into the corresponding items of Cube
    metadata.

    Args:

    * collation:
        A FieldCollation object.

    Returns:
        A :class:`iris.fileformats.rules.ConversionMetadata` object.

    """
    # For all the scalar conversions all fields in the collation will
    # give the same result, so the choice is arbitrary.
    field = collation.fields[0]

    # All the "other" rules.
    (references, standard_name, long_name, units, attributes, cell_methods,
     dim_coords_and_dims, aux_coords_and_dims) = _all_other_rules(field)

    # Adjust any dimension bindings to account for the extra leading
    # dimensions added by the collation.
    if collation.vector_dims_shape:
        n_collation_dims = len(collation.vector_dims_shape)
        dim_coords_and_dims = _adjust_dims(dim_coords_and_dims,
                                           n_collation_dims)
        aux_coords_and_dims = _adjust_dims(aux_coords_and_dims,
                                           n_collation_dims)

    # "Normal" (non-cross-sectional) time values
    vector_headers = collation.element_arrays_and_dims
    # If the collation doesn't define a vector of values for a
    # particular header then it must be constant over all fields in the
    # collation. In which case it's safe to get the value from any field.
    t1, t1_dims = vector_headers.get('t1', (field.t1, ()))
    t2, t2_dims = vector_headers.get('t2', (field.t2, ()))
    lbft, lbft_dims = vector_headers.get('lbft', (field.lbft, ()))
    coords_and_dims = _convert_time_coords(field.lbcode, field.lbtim,
                                           field.time_unit('hours'),
                                           t1, t2, lbft,
                                           t1_dims, t2_dims, lbft_dims)
    dim_coord_dims = set()
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # "Normal" (non-cross-sectional) vertical levels
    blev, blev_dims = vector_headers.get('blev', (field.blev, ()))
    lblev, lblev_dims = vector_headers.get('lblev', (field.lblev, ()))
    bhlev, bhlev_dims = vector_headers.get('bhlev', (field.bhlev, ()))
    bhrlev, bhrlev_dims = vector_headers.get('bhrlev', (field.bhrlev, ()))
    brsvd1, brsvd1_dims = vector_headers.get('brsvd1', (field.brsvd[0], ()))
    brsvd2, brsvd2_dims = vector_headers.get('brsvd2', (field.brsvd[1], ()))
    brlev, brlev_dims = vector_headers.get('brlev', (field.brlev, ()))
    # Find all the non-trivial dimension values
    dims = set(filter(None, [blev_dims, lblev_dims, bhlev_dims, bhrlev_dims,
                             brsvd1_dims, brsvd2_dims, brlev_dims]))
    if len(dims) > 1:
        raise TranslationError('Unsupported multiple values for vertical '
                               'dimension.')
    if dims:
        v_dims = dims.pop()
        if len(v_dims) > 1:
            raise TranslationError('Unsupported multi-dimension vertical '
                                   'headers.')
    else:
        v_dims = ()
    coords_and_dims, factories = _convert_vertical_coords(field.lbcode,
                                                          field.lbvc,
                                                          blev, lblev,
                                                          field.stash,
                                                          bhlev, bhrlev,
                                                          brsvd1, brsvd2,
                                                          brlev, v_dims)
    _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims,
                 aux_coords_and_dims)

    # Realization (aka ensemble) (--> scalar coordinates)
    aux_coords_and_dims.extend(_convert_scalar_realization_coords(
        lbrsvd4=field.lbrsvd[3]))

    # Pseudo-level coordinate (--> scalar coordinates)
    aux_coords_and_dims.extend(_convert_scalar_pseudo_level_coords(
        lbuser5=field.lbuser[4]))

    return ConversionMetadata(factories, references, standard_name, long_name,
                              units, attributes, cell_methods,
                              dim_coords_and_dims, aux_coords_and_dims)
示例#19
0
 def test_hourly_mean(self):
     # lbtim.ia = 1 -> hourly
     field = mock.MagicMock(lbproc=128, lbtim=mock.Mock(ia=1, ib=2, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('mean', 'time', '1 hour')]
     self.assertEqual(res, expected)
示例#20
0
 def test_climatology_max(self):
     field = mock.MagicMock(lbproc=4096,
                            lbtim=mock.Mock(ia=24, ib=3, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('minimum', 'time')]
     self.assertEqual(res, expected)
示例#21
0
 def test_custom_max(self):
     field = mock.MagicMock(lbproc=8192, lbtim=mock.Mock(ia=47, ib=2, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('maximum', 'time', '47 hour')]
     self.assertEqual(res, expected)
示例#22
0
    def test_diff_month(self):
        field = self._make_field(lbmon=3, lbmond=4)
        field.mock_add_spec(self._spec)
        res = _all_other_rules(field)[AUX_COORDS_INDEX]

        self.assertCoordsAndDimsListsMatch(res, [])
示例#23
0
 def test_daily_min(self):
     # lbproc = 4096 -> min
     field = mock.MagicMock(lbproc=4096, lbtim=mock.Mock(ia=24, ib=2, ic=3))
     res = _all_other_rules(field)[CELL_METHODS_INDEX]
     expected = [CellMethod('minimum', 'time', '24 hour')]
     self.assertEqual(res, expected)