def cube_delta(cube, coord): """ Given a cube calculate the difference between each value in the given coord's direction. Args: * coord either a Coord instance or the unique name of a coordinate in the cube. If a Coord instance is provided, it does not necessarily have to exist in the cube. Example usage:: change_in_temperature_wrt_pressure = cube_delta(temperature_cube, 'pressure') .. note:: Missing data support not yet implemented. """ # handle the case where a user passes a coordinate name if isinstance(coord, basestring): coord = cube.coord(coord) if coord.ndim != 1: raise iris.exceptions.CoordinateMultiDimError(coord) # Try and get a coord dim delta_dims = cube.coord_dims(coord) if (coord.shape[0] == 1 and not getattr(coord, 'circular', False)) or not delta_dims: raise ValueError( 'Cannot calculate delta over "%s" as it has length of 1.' % coord.name()) delta_dim = delta_dims[0] # Calculate the actual delta, taking into account whether the given coordinate is circular delta_cube_data = delta(cube.data, delta_dim, circular=getattr(coord, 'circular', False)) # If the coord/dim is circular there is no change in cube shape if getattr(coord, 'circular', False): delta_cube = cube.copy(data=delta_cube_data) else: # Subset the cube to the appropriate new shape by knocking off the last row of the delta dimension subset_slice = [slice(None, None)] * cube.ndim subset_slice[delta_dim] = slice(None, -1) delta_cube = cube[tuple(subset_slice)] delta_cube.data = delta_cube_data # Replace the delta_dim coords with midpoints (no shape change if circular). for cube_coord in cube.coords(dimensions=delta_dim): delta_cube.replace_coord( _construct_midpoint_coord(cube_coord, circular=getattr(coord, 'circular', False))) delta_cube.rename('change_in_%s_wrt_%s' % (delta_cube.name(), coord.name())) return delta_cube
def cube_delta(cube, coord): """ Given a cube calculate the difference between each value in the given coord's direction. Args: * coord either a Coord instance or the unique name of a coordinate in the cube. If a Coord instance is provided, it does not necessarily have to exist in the cube. Example usage:: change_in_temperature_wrt_pressure = \ cube_delta(temperature_cube, 'pressure') .. note:: Missing data support not yet implemented. """ # handle the case where a user passes a coordinate name if isinstance(coord, six.string_types): coord = cube.coord(coord) if coord.ndim != 1: raise iris.exceptions.CoordinateMultiDimError(coord) # Try and get a coord dim delta_dims = cube.coord_dims(coord.name()) if (coord.shape[0] == 1 and not getattr(coord, "circular", False)) or not delta_dims: raise ValueError("Cannot calculate delta over {!r} as it has " "length of 1.".format(coord.name())) delta_dim = delta_dims[0] # Calculate the actual delta, taking into account whether the given # coordinate is circular. delta_cube_data = delta(cube.data, delta_dim, circular=getattr(coord, "circular", False)) # If the coord/dim is circular there is no change in cube shape if getattr(coord, "circular", False): delta_cube = cube.copy(data=delta_cube_data) else: # Subset the cube to the appropriate new shape by knocking off # the last row of the delta dimension. subset_slice = [slice(None, None)] * cube.ndim subset_slice[delta_dim] = slice(None, -1) delta_cube = cube[tuple(subset_slice)] delta_cube.data = delta_cube_data # Replace the delta_dim coords with midpoints # (no shape change if circular). for cube_coord in cube.coords(dimensions=delta_dim): delta_cube.replace_coord(_construct_midpoint_coord(cube_coord, circular=getattr(coord, "circular", False))) delta_cube.rename("change_in_{}_wrt_{}".format(delta_cube.name(), coord.name())) return delta_cube