Example #1
0
    def _regrid_variable(self, var_cube: Cube, unit: str) -> Cube:
        """
        Sorts spatial coordinates in ascending order, regrids the input
        variable onto the topography grid and converts to the required
        units.  This function does not modify the input variable cube.

        Args:
            var_cube:
                Cube containing input variable data
            unit:
                Required unit for this variable

        Returns:
            Cube containing regridded variable data
        """
        for axis in ["x", "y"]:
            var_cube = sort_coord_in_cube(var_cube, var_cube.coord(axis=axis))

        enforce_coordinate_ordering(
            var_cube,
            [var_cube.coord(axis="y").name(),
             var_cube.coord(axis="x").name()])

        regridder = iris.analysis.Linear()
        out_cube = var_cube.regrid(self.topography, regridder)
        out_cube.data = out_cube.data.astype(np.float32)
        out_cube.convert_units(unit)
        return out_cube
Example #2
0
    def process(self, cube: Cube, input_land: Cube, output_land: Cube) -> Cube:
        """
        Update cube.data so that output_land and sea points match an input_land
        or sea point respectively so long as one is present within the
        specified vicinity radius. Note that before calling this plugin the
        input land mask MUST be checked against the source grid, to ensure
        the grids match.

        Args:
            cube:
                Cube of data to be updated (on same grid as output_land).
            input_land:
                Cube of land_binary_mask data on the grid from which "cube" has
                been reprojected (it is expected that the iris.analysis.Nearest
                method would have been used). Land points should be set to one
                and sea points set to zero.
                This is used to determine where the input model data is
                representing land and sea points.
            output_land:
                Cube of land_binary_mask data on target grid.

        Returns:
            Cube of regridding results.
        """
        # Check cube and output_land are on the same grid:
        if not spatial_coords_match([cube, output_land]):
            raise ValueError("X and Y coordinates do not match for cubes {}"
                             "and {}".format(repr(cube), repr(output_land)))
        self.output_land = output_land

        # Regrid input_land to output_land grid.
        self.input_land = input_land.regrid(self.output_land, self.regridder)

        # Slice over x-y grids for multi-realization data.
        result = iris.cube.CubeList()

        # Reset cache as input_land and output_land have changed
        self._get_matches.cache_clear()
        for xyslice in cube.slices(
            [cube.coord(axis="y"), cube.coord(axis="x")]):
            # Store and copy cube ready for the output data
            self.nearest_cube = xyslice
            self.output_cube = self.nearest_cube.copy()

            # Update sea points that were incorrectly sourced from land points
            self.correct_where_input_true(0)

            # Update land points that were incorrectly sourced from sea points
            self.correct_where_input_true(1)

            result.append(self.output_cube)

        result = result.merge_cube()
        return result
Example #3
0
    def _regrid_to_target(self, cube: Cube, target_grid: Cube,
                          regridded_title: Optional[str]) -> Cube:
        """
        Regrid cube to target_grid, inherit grid attributes and update title

        Args:
            cube:
                Cube to be regridded
            target_grid:
                Data on the target grid. If regridding with mask, this cube
                should contain land-sea mask data to be used in adjusting land
                and sea points after regridding.
            regridded_title:
                New value for the "title" attribute to be used after
                regridding. If not set, a default value is used.

        Returns:
            Regridded cube with updated attributes
        """
        regridder = Linear(extrapolation_mode=self.extrapolation_mode)
        if "nearest" in self.regrid_mode:
            regridder = Nearest(extrapolation_mode=self.extrapolation_mode)
        cube = cube.regrid(target_grid, regridder)

        if self.REGRID_REQUIRES_LANDMASK[self.regrid_mode]:
            cube = self._adjust_landsea(cube, target_grid)

        # identify grid-describing attributes on source cube that need updating
        required_grid_attributes = [
            attr for attr in cube.attributes if attr in MOSG_GRID_ATTRIBUTES
        ]
        # update attributes if available on target grid, otherwise remove
        for key in required_grid_attributes:
            if key in target_grid.attributes:
                cube.attributes[key] = target_grid.attributes[key]
            else:
                cube.attributes.pop(key)

        cube.attributes["title"] = (MANDATORY_ATTRIBUTE_DEFAULTS["title"]
                                    if regridded_title is None else
                                    regridded_title)

        return cube
Example #4
0
    def test(self):
        # Test that Cube.regrid() just defers to the regridder of the
        # given scheme.

        # Define a fake scheme and its associated regridder which just
        # capture their arguments and return them in place of the
        # regridded cube.
        class FakeRegridder(object):
            def __init__(self, *args):
                self.args = args

            def __call__(self, cube):
                return self.args + (cube,)

        class FakeScheme(object):
            def regridder(self, src, target):
                return FakeRegridder(self, src, target)

        cube = Cube(0)
        scheme = FakeScheme()
        result = cube.regrid(mock.sentinel.TARGET, scheme)
        self.assertEqual(result, (scheme, cube, mock.sentinel.TARGET, cube))
Example #5
0
    def _regrid_to_target(
        self,
        cube: Cube,
        target_grid: Cube,
        regridded_title: Optional[str],
        regrid_mode: str,
    ) -> Cube:
        """
        Regrid cube to target_grid, inherit grid attributes and update title

        Args:
            cube:
                Cube to be regridded
            target_grid:
                Data on the target grid. If regridding with mask, this cube
                should contain land-sea mask data to be used in adjusting land
                and sea points after regridding.
            regridded_title:
                New value for the "title" attribute to be used after
                regridding. If not set, a default value is used.
            regrid_mode:
                "bilinear","nearest","nearest-with-mask",
                "nearest-2","nearest-with-mask-2","bilinear-2","bilinear-with-mask-2"

        Returns:
            Regridded cube with updated attributes.
        """
        if regrid_mode in (
                "nearest-with-mask",
                "nearest-with-mask-2",
                "bilinear-with-mask-2",
        ):
            if self.landmask_name not in self.landmask_source_grid.name():
                msg = "Expected {} in input_landmask cube but found {}".format(
                    self.landmask_name, repr(self.landmask_source_grid))
                warnings.warn(msg)

            if self.landmask_name not in target_grid.name():
                msg = "Expected {} in target_grid cube but found {}".format(
                    self.landmask_name, repr(target_grid))
                warnings.warn(msg)

        # basic categories (1) Iris-based (2) new nearest based  (3) new bilinear-based
        if regrid_mode in ("bilinear", "nearest", "nearest-with-mask"):
            if "nearest" in regrid_mode:
                regridder = Nearest(extrapolation_mode=self.extrapolation_mode)
            else:
                regridder = Linear(extrapolation_mode=self.extrapolation_mode)
            cube = cube.regrid(target_grid, regridder)

            # Iris regridding is used, and then adjust if land_sea mask is considered
            if self.REGRID_REQUIRES_LANDMASK[regrid_mode]:
                cube = AdjustLandSeaPoints(
                    vicinity_radius=self.landmask_vicinity,
                    extrapolation_mode=self.extrapolation_mode,
                )(cube, self.landmask_source_grid, target_grid)

        # new version of nearest/bilinear option with/without land-sea mask
        elif regrid_mode in (
                "nearest-2",
                "nearest-with-mask-2",
                "bilinear-2",
                "bilinear-with-mask-2",
        ):
            cube = RegridWithLandSeaMask(
                regrid_mode=regrid_mode,
                vicinity_radius=self.landmask_vicinity)(
                    cube, self.landmask_source_grid, target_grid)

        # identify grid-describing attributes on source cube that need updating
        required_grid_attributes = [
            attr for attr in cube.attributes if attr in MOSG_GRID_ATTRIBUTES
        ]

        # update attributes if available on target grid, otherwise remove
        for key in required_grid_attributes:
            if key in target_grid.attributes:
                cube.attributes[key] = target_grid.attributes[key]
            else:
                cube.attributes.pop(key)

        cube.attributes["title"] = (MANDATORY_ATTRIBUTE_DEFAULTS["title"]
                                    if regridded_title is None else
                                    regridded_title)

        return cube
regridded_data_emission = cube2.interpolate([('latitude', lat01),
                                             ('longitude', lon01)],
                                            iris.analysis.Linear())
print(regridded_data_emission.shape, 'regrid_emission_shape')

sum_regridded_emission = np.nansum(np.nansum(np.nansum(
    regridded_data_emission.data, axis=2),
                                             axis=1),
                                   axis=0)
print(sum_regridded_emission, 'sum_regridded_emission')

regridded_data_emission.coord('longitude').guess_bounds()
regridded_data_emission.coord('latitude').guess_bounds()

scheme = iris.analysis.AreaWeighted(mdtol=1)
regridded_data_emission2 = cube2.regrid(regridded_data_emission, scheme)

sum_regridded_emission2 = np.nansum(np.nansum(np.nansum(
    regridded_data_emission2.data, axis=2),
                                              axis=1),
                                    axis=0)
print(sum_regridded_emission2, 'sum_regridded_emission2')

lat_n = regridded_data_emission.coord('latitude')
#print(lat_n.shape)
lat_n = lat_n.points[:]
lon_n = regridded_data_emission.coord('longitude')
#print(lon_n.shape)
lon_n = lon_n.points[:]

lat_n_min, lon_n_min = np.nanmin(lat_n), np.nanmin(lon_n)