def test_365_calendar(self): f = mock.MagicMock(lbtim=SplittableInt(4, { 'ia': 2, 'ib': 1, 'ic': 0 }), lbyr=2013, lbmon=1, lbdat=1, lbhr=12, lbmin=0, lbsec=0, spec=PPField3) f.time_unit = types.MethodType(PPField3.time_unit, f) f.calendar = iris.unit.CALENDAR_365_DAY (factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = convert(f) def is_t_coord(coord_and_dims): coord, dims = coord_and_dims return coord.standard_name == 'time' coords_and_dims = filter(is_t_coord, aux_coords_and_dims) self.assertEqual(len(coords_and_dims), 1) coord, dims = coords_and_dims[0] self.assertEqual(guess_coord_axis(coord), 'T') self.assertEqual(coord.units.calendar, '365_day')
def key_func(coord): return ( axes.get(guess_coord_axis(coord), len(axes) + 1), coord.name(), cube.coord_dims(coord), )
def test_365_calendar(self): f = mock.MagicMock( lbtim=SplittableInt(4, {"ia": 2, "ib": 1, "ic": 0}), lbyr=2013, lbmon=1, lbdat=1, lbhr=12, lbmin=0, lbsec=0, spec=PPField3, ) f.time_unit = six.create_bound_method(PPField3.time_unit, f) f.calendar = cf_units.CALENDAR_365_DAY ( factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims, ) = convert(f) def is_t_coord(coord_and_dims): coord, dims = coord_and_dims return coord.standard_name == "time" coords_and_dims = list(filter(is_t_coord, aux_coords_and_dims)) self.assertEqual(len(coords_and_dims), 1) coord, dims = coords_and_dims[0] self.assertEqual(guess_coord_axis(coord), "T") self.assertEqual(coord.units.calendar, "365_day")
def __init__(self, cube): """ Represents the cube metadata and associated coordinate metadata that allows suitable cubes for concatenation to be identified. Args: * cube: The :class:`iris.cube.Cube` source-cube. """ self.aux_coords_and_dims = [] self.aux_metadata = [] self.dim_coords = cube.dim_coords self.dim_metadata = [] self.mdi = None self.ndim = cube.ndim self.scalar_coords = [] # Determine whether there are any anonymous cube dimensions. covered = set(cube.coord_dims(coord)[0] for coord in self.dim_coords) self.anonymous = covered != set(range(self.ndim)) self.defn = cube.metadata self.data_type = cube.data.dtype if ma.isMaskedArray(cube.data): # Only set when we're dealing with a masked payload. self.mdi = cube.data.fill_value # # Collate the dimension coordinate metadata. # for coord in self.dim_coords: metadata = _CoordMetaData(coord, cube.coord_dims(coord)) self.dim_metadata.append(metadata) # # Collate the auxiliary coordinate metadata and scalar coordinates. # axes = dict(T=0, Z=1, Y=2, X=3) # Coordinate sort function - by guessed coordinate axis, then # by coordinate definition, then by dimensions, in ascending order. key_func = lambda coord: (axes.get(guess_coord_axis(coord), len(axes) + 1), coord._as_defn(), cube.coord_dims(coord)) for coord in sorted(cube.aux_coords, key=key_func): dims = cube.coord_dims(coord) if dims: metadata = _CoordMetaData(coord, dims) self.aux_metadata.append(metadata) coord_and_dims = _CoordAndDims(coord, tuple(dims)) self.aux_coords_and_dims.append(coord_and_dims) else: self.scalar_coords.append(coord)
def sort_coords(coord): """ Sorts a list of DimCoords trying to ensure that dates and pressure levels appear first and the longitude and latitude appear last in the correct order. """ order = {'T': -2, 'Z': -1, 'X': 1, 'Y': 2} axis = guess_coord_axis(coord) return (order.get(axis, 0), coord and coord.name())
def transform(self): # Modify the attribute 'positive' so the 'guess' function # won't recognize the 'soil_level' as axis Z for cube in self._cubes: if cube.coords('soil_model_level_number'): coord = cube.coord('soil_model_level_number') if coord.attributes: coord.attributes.pop('positive') guess_coord_axis(coord) # This handles the depth below land surface if cube.coords('depth'): coord = cube.coord('depth') if coord.attributes: coord.attributes.pop('positive') guess_coord_axis(coord) # Make cfdata be consitent with iris CF_GRIB2_TABLE if 'type_cloud_area_fraction' in cube.name(): cube.units = '%' if cube.name() == 'soil_moisture_content': cube.units = 'kg m-2' if cube.name() == 'canopy_water_amount': cube.units = 'kg m-2'
def test_soil_levels(self): field = mock.MagicMock(lbvc=6, blev=1234) (factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = convert(field) def is_model_level_coord(coord_and_dims): coord, dims = coord_and_dims return coord.standard_name == 'model_level_number' coords_and_dims = filter(is_model_level_coord, aux_coords_and_dims) self.assertEqual(len(coords_and_dims), 1) coord, dims = coords_and_dims[0] self.assertEqual(coord.points, 1234) self.assertIsNone(coord.bounds) self.assertEqual(guess_coord_axis(coord), 'Z')
def test_potential_temperature_levels(self): potm_value = 27.32 field = mock.MagicMock(lbvc=19, blev=potm_value) (factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = convert(field) def is_potm_level_coord(coord_and_dims): coord, dims = coord_and_dims return coord.standard_name == 'air_potential_temperature' coords_and_dims = filter(is_potm_level_coord, aux_coords_and_dims) self.assertEqual(len(coords_and_dims), 1) coord, dims = coords_and_dims[0] self.assertArrayEqual(coord.points, [potm_value]) self.assertIsNone(coord.bounds) self.assertEqual(guess_coord_axis(coord), 'Z')
def test_365_calendar(self): f = mock.MagicMock(lbtim=SplittableInt(4, {'ia': 2, 'ib': 1, 'ic': 0}), lbyr=2013, lbmon=1, lbdat=1, lbhr=12, lbmin=0, lbsec=0, spec=PPField3) f.time_unit = types.MethodType(PPField3.time_unit, f) f.calendar = iris.unit.CALENDAR_365_DAY (factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims) = convert(f) def is_t_coord(coord_and_dims): coord, dims = coord_and_dims return coord.standard_name == 'time' coords_and_dims = filter(is_t_coord, aux_coords_and_dims) self.assertEqual(len(coords_and_dims), 1) coord, dims = coords_and_dims[0] self.assertEqual(guess_coord_axis(coord), 'T') self.assertEqual(coord.units.calendar, '365_day')
def test_365_calendar(self): f = mock.MagicMock( lbtim=SplittableInt(4, { "ia": 2, "ib": 1, "ic": 0 }), lbyr=2013, lbmon=1, lbdat=1, lbhr=12, lbmin=0, lbsec=0, t1=cftime.datetime(2013, 1, 1, 12, 0, 0), t2=cftime.datetime(2013, 1, 2, 12, 0, 0), spec=PPField3, ) f.time_unit = MethodType(PPField3.time_unit, f) f.calendar = cf_units.CALENDAR_365_DAY ( factories, references, standard_name, long_name, units, attributes, cell_methods, dim_coords_and_dims, aux_coords_and_dims, ) = convert(f) def is_t_coord(coord_and_dims): coord, dims = coord_and_dims return coord.standard_name == "time" coords_and_dims = list(filter(is_t_coord, aux_coords_and_dims)) self.assertEqual(len(coords_and_dims), 1) coord, dims = coords_and_dims[0] self.assertEqual(guess_coord_axis(coord), "T") self.assertEqual(coord.units.calendar, "365_day")
def get_dim_coord(cube, axis): """ Return a coordinate from a cube based on the axis it represents. Uses :py:func:`iris.util.guess_coord_axis` to heuristically match a dimensional coordinate with the requested axis. Adapted from https://github.com/LSaffin/iris-extensions Parameters ---------- cube: iris.cube.Cube Cube with the desired coordinate. axis: str The co-ordinate axis to take from the cube. Must be one of X, Y, Z, T. Returns ------- iris.coords.DimCoord The dimensional coordinate matching the requested axis on the given cube. Raises ------ ArgumentError: If axis is not one of {X, Y, Z, T}. NotFoundError: If the cube does not contain a coord with the requested axis. """ _allowed = ["X", "Y", "Z", "T"] axis = axis.upper() # If the axis supplied is not correct raise an error if axis not in _allowed: raise ArgumentError(f"Axis must be one of {_allowed}, {axis} is given.") # Loop over dimensional coords in the cube for coord in cube.dim_coords: # Return the coordinate if it matches the axis if axis == guess_coord_axis(coord): return coord # If no coordinate matches raise an error raise NotFoundError(f"Cube has no coordinate for axis {axis}")
def key_func(coord): return (axes.get(guess_coord_axis(coord), len(axes) + 1), coord._as_defn(), cube.coord_dims(coord))