def __init__(self, src_cube, tgt_grid_cube, method, projection=None): """ Create a regridder for conversions between the source and target grids. Args: * src_cube: The :class:`~iris.cube.Cube` providing the source points. * tgt_grid_cube: The :class:`~iris.cube.Cube` providing the target grid. * method: Either 'linear' or 'nearest'. * projection: The projection in which the interpolation is performed. If None, a PlateCarree projection is used. Defaults to None. """ # Validity checks. if not isinstance(src_cube, iris.cube.Cube): raise TypeError("'src_cube' must be a Cube") if not isinstance(tgt_grid_cube, iris.cube.Cube): raise TypeError("'tgt_grid_cube' must be a Cube") # Snapshot the state of the target cube to ensure that the regridder # is impervious to external changes to the original source cubes. self._tgt_grid = snapshot_grid(tgt_grid_cube) # Check the target grid units. for coord in self._tgt_grid: self._check_units(coord) # Whether to use linear or nearest-neighbour interpolation. if method not in ('linear', 'nearest'): msg = 'Regridding method {!r} not supported.'.format(method) raise ValueError(msg) self._method = method src_x_coord, src_y_coord = get_xy_coords(src_cube) if src_x_coord.coord_system != src_y_coord.coord_system: raise ValueError("'src_cube' lateral geographic coordinates have " "differing coordinate sytems.") if src_x_coord.coord_system is None: raise ValueError("'src_cube' lateral geographic coordinates have " "no coordinate sytem.") tgt_x_coord, tgt_y_coord = get_xy_dim_coords(tgt_grid_cube) if tgt_x_coord.coord_system != tgt_y_coord.coord_system: raise ValueError("'tgt_grid_cube' lateral geographic coordinates " "have differing coordinate sytems.") if tgt_x_coord.coord_system is None: raise ValueError("'tgt_grid_cube' lateral geographic coordinates " "have no coordinate sytem.") if projection is None: globe = src_x_coord.coord_system.as_cartopy_globe() projection = ccrs.Sinusoidal(globe=globe) self._projection = projection
def __call__(self, src_cube): """ Regrid this :class:`~iris.cube.Cube` on to the target grid of this :class:`UnstructuredProjectedRegridder`. The given cube must be defined with the same grid as the source grid used to create this :class:`UnstructuredProjectedRegridder`. Args: * src_cube: A :class:`~iris.cube.Cube` to be regridded. Returns: A cube defined with the horizontal dimensions of the target and the other dimensions from this cube. The data values of this cube will be converted to values on the new grid using either nearest-neighbour or linear interpolation. """ # Validity checks. if not isinstance(src_cube, iris.cube.Cube): raise TypeError("'src' must be a Cube") src_x_coord, src_y_coord = get_xy_coords(src_cube) tgt_x_coord, tgt_y_coord = self._tgt_grid src_cs = src_x_coord.coord_system if src_x_coord.coord_system != src_y_coord.coord_system: raise ValueError( "'src' lateral geographic coordinates have " "differing coordinate sytems." ) if src_cs is None: raise ValueError( "'src' lateral geographic coordinates have " "no coordinate sytem." ) # Check the source grid units. for coord in (src_x_coord, src_y_coord): self._check_units(coord) (src_x_dim,) = src_cube.coord_dims(src_x_coord) (src_y_dim,) = src_cube.coord_dims(src_y_coord) if src_x_dim != src_y_dim: raise ValueError( "'src' lateral geographic coordinates should map " "the same dimension." ) src_xy_dim = src_x_dim # Compute the interpolated data values. data = self._regrid( src_cube.data, src_xy_dim, src_x_coord, src_y_coord, tgt_x_coord, tgt_y_coord, self._projection, method=self._method, ) # Wrap up the data as a Cube. regrid_callback = functools.partial( self._regrid, method=self._method, projection=self._projection ) new_cube = self._create_cube( data, src_cube, src_xy_dim, src_x_coord, src_y_coord, tgt_x_coord, tgt_y_coord, regrid_callback, ) return new_cube