コード例 #1
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_field_with_corners(self):
        """Test with_corners as True and False when regridding Fields."""

        ofield = self.get_ofield()
        ofield.spatial.crs = Spherical()
        ofield2 = deepcopy(ofield)
        sources = [ofield, ofield2]
        destination_field = deepcopy(ofield)

        self.assertIsNotNone(destination_field.spatial.geom.polygon)
        for regridded in iter_regridded_fields(sources, destination_field, with_corners=False):
            self.assertIsNone(regridded.spatial.grid.row.bounds)
            self.assertIsNone(regridded.spatial.grid.col.bounds)
            self.assertIsNone(regridded.spatial.grid.corners)
            self.assertIsNone(regridded.spatial.geom.polygon)

        # Check that the destination grid is not modified.
        self.assertIsNotNone(destination_field.spatial.grid.row.bounds)

        # Remove corners from the destination and make sure that this is caught when with_corners is True.
        dest = deepcopy(destination_field).spatial
        dest.grid.row.remove_bounds()
        dest.grid.col.remove_bounds()
        dest.grid._corners = None
        self.assertIsNone(dest.grid.corners)
        with self.assertRaises(CornersInconsistentError):
            list(iter_regridded_fields(sources, dest, with_corners=True))
        # If this is now false, then there should be no problem as only centroids are used.
        list(iter_regridded_fields(sources, dest, with_corners=False))
        # This is also the case with 'auto'.
        list(iter_regridded_fields(sources, dest, with_corners="auto"))
コード例 #2
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_fields(self):
        """Test with equivalent input and output expectations. The shapes of the grids are equal."""

        ofield = self.get_ofield()
        ofield.spatial.crs = Spherical()
        ofield2 = deepcopy(ofield)
        sources = [ofield, ofield2]
        destination_field = deepcopy(ofield)

        keywords = dict(use_sdim=[True, False], split=[False, True])

        for k in itr_products_keywords(keywords, as_namedtuple=True):
            if k.use_sdim:
                destination = destination_field.spatial
                sdim = destination
            else:
                destination = destination_field
                sdim = destination.spatial
            self.assertIsNotNone(sdim.grid.row)
            self.assertIsNotNone(sdim.grid.col)
            for ctr, regridded in enumerate(
                iter_regridded_fields(sources, destination, with_corners="auto", value_mask=None, split=k.split)
            ):
                self.assertIsInstance(regridded, Field)
                self.assertNumpyAll(regridded.spatial.grid.value, sdim.grid.value)
                self.assertEqual(regridded.spatial.crs, sdim.crs)
                self.assertNumpyAll(regridded.spatial.grid.row.value, sdim.grid.row.value)
                self.assertNumpyAll(regridded.spatial.grid.row.bounds, sdim.grid.row.bounds)
                self.assertNumpyAll(regridded.spatial.grid.col.value, sdim.grid.col.value)
                self.assertNumpyAll(regridded.spatial.grid.col.bounds, sdim.grid.col.bounds)
                for variable in regridded.variables.itervalues():
                    self.assertGreater(variable.value.mean(), 2.0)
                    self.assertNumpyAll(variable.value, sources[ctr].variables[variable.alias].value)
                    self.assertFalse(np.may_share_memory(variable.value, sources[ctr].variables[variable.alias].value))
            self.assertEqual(ctr, 1)
コード例 #3
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_fields_problem_bounds(self):
        """Test a dataset with crap bounds will work when with_corners is False."""

        dst = self.test_data.get_rd("cancm4_tas").get()[:, :, :, 20:25, 30:35]
        dst.spatial.crs = Spherical()
        src = deepcopy(dst[0, 0, 0, :, :])

        egrid_dst = get_esmf_grid_from_sdim(dst.spatial)
        egrid_src = get_esmf_grid_from_sdim(src.spatial)
        self.assertEqual(egrid_dst.mask[0].sum(), 25)
        self.assertEqual(egrid_src.mask[0].sum(), 25)
        self.assertNumpyAll(egrid_dst.coords[0][0], egrid_src.coords[0][0])
        self.assertNumpyAll(egrid_dst.coords[0][1], egrid_src.coords[0][1])

        ret = list(iter_esmf_fields(src))
        self.assertEqual(len(ret), 1)
        variable_alias, efield, tidx = ret[0]
        self.assertNumpyAll(efield.grid.coords[0][0], dst.spatial.grid.value.data[1])
        self.assertNumpyAll(efield.grid.coords[0][1], dst.spatial.grid.value.data[0])

        ret = list(iter_regridded_fields([src], dst, with_corners=False))[0]
        actual = dst[0, 0, 0, :, :].variables.first().value
        to_test = ret.variables.first().value
        self.assertFalse(to_test.mask.any())

        self.assertNumpyAllClose(to_test.data, actual.data)
        self.assertNumpyAll(to_test.mask, actual.mask)
コード例 #4
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_fields_differing_crs(self):
        """Test exception raised when source and destination CRS values are not equal."""

        ofield = self.get_ofield()
        ofield2 = deepcopy(ofield)
        sources = [ofield, ofield2]
        destination_field = deepcopy(ofield)

        sources[1].spatial.crs = CoordinateReferenceSystem(epsg=2136)

        with self.assertRaises(RegriddingError):
            list(iter_regridded_fields(sources, destination_field))
コード例 #5
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_fields_value_mask(self):
        """Test with a value mask on the destination."""

        ofield = self.get_ofield()
        ofield.spatial.crs = Spherical()
        ofield2 = deepcopy(ofield)
        sources = [ofield, ofield2]
        destination_field = deepcopy(ofield)

        value_mask = np.zeros(destination_field.spatial.shape, dtype=bool)
        value_mask[1, 1] = True

        for regridded in iter_regridded_fields(sources, destination_field, value_mask=value_mask):
            self.assertTrue(np.all(regridded.variables.first().value.mask[:, :, :, 1, 1]))
コード例 #6
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_fields_partial_extents(self):
        """Test regridding with fields that partially overlap."""

        rd = self.test_data.get_rd("cancm4_tas")
        # california and nevada
        coll = ocgis.OcgOperations(
            dataset=rd, geom="state_boundaries", select_ugid=[23, 25], snippet=True, vector_wrap=False
        ).execute()
        source = coll[25]["tas"]
        destination = coll[23]["tas"]
        source.spatial.crs = Spherical()
        destination.spatial.crs = Spherical()

        res = list(iter_regridded_fields([source], destination))
        self.assertEqual(res[0].variables["tas"].value.mask.sum(), 6)
コード例 #7
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_fields_nonoverlapping_extents(self):
        """Test regridding with fields that do not spatially overlap."""

        rd = self.test_data.get_rd("cancm4_tas")
        # nebraska and california
        coll = ocgis.OcgOperations(
            dataset=rd, geom="state_boundaries", select_ugid=[16, 25], snippet=True, vector_wrap=False
        ).execute()
        source = coll[25]["tas"]
        destination = coll[16]["tas"]
        source.spatial.crs = Spherical()
        destination.spatial.crs = Spherical()

        with self.assertRaises(RegriddingError):
            list(iter_regridded_fields([source], destination))
コード例 #8
0
ファイル: test_base.py プロジェクト: NCPP/ocgis
    def test_iter_regridded_fields_different_grid_shapes(self):
        """Test regridding a downscaled dataset to GCM output. The input and output grids have different shapes."""

        downscaled = self.test_data.get_rd("maurer_2010_tas")
        downscaled.time_region = {"month": [2], "year": [1990]}
        downscaled = downscaled.get()
        poly = make_poly([37, 43], [-104, -94])
        downscaled = downscaled.get_intersects(poly)
        downscaled.spatial.unwrap()
        downscaled.spatial.crs = Spherical()

        gcm = self.test_data.get_rd("cancm4_tas")
        gcm = gcm.get()
        poly = make_poly([37, 43], [-104 + 360, -94 + 360])
        gcm = gcm.get_intersects(poly)
        gcm.spatial.crs = Spherical()

        # add masked values to the source and destination
        self.assertFalse(downscaled.spatial.get_mask().any())
        self.assertFalse(gcm.spatial.get_mask().any())

        mask = gcm.spatial.get_mask()
        mask[1, 3] = True
        gcm.spatial.set_mask(mask)

        desired = {
            "std": 3.1385237308556095,
            "trace": -11.13192056119442,
            "min": -11.858446,
            "max": 9.8645229,
            "shape": (1, 28, 1, 3, 5),
            "mean": 0.047387103645169008,
        }

        for regridded in iter_regridded_fields([downscaled], gcm):
            self.assertEqual(regridded.shape, (1, 28, 1, 3, 5))
            self.assertEqual(regridded.variables.keys(), ["tas"])
            self.assertDescriptivesAlmostEqual(desired, regridded.variables["tas"].value)
            self.assertNumpyAll(gcm.spatial.get_mask(), mask)
            for variable in regridded.variables.itervalues():
                vmask = variable.value.mask
                self.assertTrue(vmask[:, :, :, 1, 3].all())
                self.assertEqual(vmask.sum(), 28)
コード例 #9
0
ファイル: test_base.py プロジェクト: HydroLogic/ocgis
    def test_iter_regridded_fields_different_grid_shapes(self):
        """Test regridding a downscaled dataset to GCM output. The input and output grids have different shapes."""

        downscaled = self.test_data.get_rd("maurer_2010_tas")
        downscaled.time_region = {"month": [2], "year": [1990]}
        downscaled = downscaled.get()
        poly = make_poly([37, 43], [-104, -94])
        downscaled = downscaled.get_intersects(poly)
        downscaled.spatial.unwrap()
        downscaled.spatial.crs = Spherical()

        gcm = self.test_data.get_rd("cancm4_tas")
        gcm = gcm.get()
        poly = make_poly([37, 43], [-104 + 360, -94 + 360])
        gcm = gcm.get_intersects(poly)
        gcm.spatial.crs = Spherical()

        # add masked values to the source and destination
        self.assertFalse(downscaled.spatial.get_mask().any())
        self.assertFalse(gcm.spatial.get_mask().any())

        mask = gcm.spatial.get_mask()
        mask[1, 3] = True
        gcm.spatial.set_mask(mask)

        dmask = downscaled.spatial.get_mask()
        dmask[:] = True
        downscaled.spatial.set_mask(dmask)
        downscaled.variables.first().value.mask[:] = True

        for regridded in iter_regridded_fields([downscaled], gcm):
            self.assertEqual(regridded.shape, (1, 28, 1, 3, 5))
            self.assertEqual(regridded.variables.keys(), ["tas"])
            self.assertAlmostEqual(regridded.variables["tas"].value.data.mean(), 0.057409391)
            self.assertNumpyAll(gcm.spatial.get_mask(), mask)
            for variable in regridded.variables.itervalues():
                vmask = variable.value.mask
                self.assertTrue(vmask[:, :, :, 1, 3].all())
                self.assertEqual(vmask.sum(), 28)
コード例 #10
0
ファイル: subset.py プロジェクト: HydroLogic/ocgis
    def _get_regridded_field_with_subset_(self, sfield, subset_sdim_for_regridding=None, with_buffer=True):
        """
        Regrid ``sfield`` subsetting the regrid destination in the process.

        :param sfield: The input field to regrid.
        :type sfield: :class:`ocgis.interface.base.field.Field`
        :param subset_sdim_for_regridding: The original, unaltered spatial dimension to use for subsetting.
        :type subset_sdim_for_regridding: :class:`ocgis.interface.base.dimension.spatial.SpatialDimension`
        :param bool with_buffer: If ``True``, buffer the geometry used to subset the destination grid.
        """

        # todo: cache spatial operations on regrid destination field

        from ocgis.regrid.base import iter_regridded_fields
        from ocgis.util.spatial.spatial_subset import SpatialSubsetOperation

        if subset_sdim_for_regridding is None:
            regrid_destination = self.ops.regrid_destination
        else:
            if with_buffer:
                # buffer the subset geometry by the resolution of the source field to give extents a chance to be
                # compatible
                buffer_value = sfield.spatial.grid.resolution
                buffer_crs = sfield.spatial.crs
            else:
                buffer_value, buffer_crs = [None, None]
            ss = SpatialSubsetOperation(self.ops.regrid_destination)
            regrid_destination = ss.get_spatial_subset('intersects', subset_sdim_for_regridding,
                                                       use_spatial_index=env.USE_SPATIAL_INDEX,
                                                       select_nearest=False, buffer_value=buffer_value,
                                                       buffer_crs=buffer_crs)

        original_sfield_crs = sfield.spatial.crs
        # check crs on the source field
        regrid_required_update_crs = False
        if not isinstance(sfield.spatial.crs, Spherical):
            # this as _assigned_ a WGS84 crs hence we cannot assume the default crs
            if isinstance(sfield.spatial.crs, WGS84) and sfield._has_assigned_coordinate_system:
                regrid_required_update_crs = True
            # the data has a coordinate system that is not WGS84
            elif not isinstance(sfield.spatial.crs, WGS84):
                regrid_required_update_crs = True
        if regrid_required_update_crs:
            # need to load values as source indices will disappear during crs update
            for variable in sfield.variables.itervalues():
                variable.value
            sfield.spatial.update_crs(Spherical())
        else:
            sfield.spatial.crs = Spherical()

        # update the coordinate system of the regrid destination if required
        try:
            destination_sdim = regrid_destination.spatial
        except AttributeError:
            # likely a spatial dimension object
            destination_sdim = regrid_destination
        update_regrid_destination_crs = False
        if not isinstance(destination_sdim.crs, Spherical):
            if isinstance(regrid_destination, Field):
                if isinstance(destination_sdim.crs, WGS84) and regrid_destination._has_assigned_coordinate_system:
                    update_regrid_destination_crs = True
                elif isinstance(destination_sdim.crs,
                                WGS84) and not regrid_destination._has_assigned_coordinate_system:
                    pass
                else:
                    update_regrid_destination_crs = True
            else:
                if not isinstance(destination_sdim.crs, Spherical):
                    update_regrid_destination_crs = True
        if update_regrid_destination_crs:
            destination_sdim.update_crs(Spherical())
        else:
            destination_sdim.crs = Spherical()

        # check that wrapping is equivalent
        if destination_sdim.wrapped_state == WrappableCoordinateReferenceSystem._flag_unwrapped:
            if sfield.spatial.wrapped_state == WrappableCoordinateReferenceSystem._flag_wrapped:
                sfield.spatial = deepcopy(sfield.spatial)
                sfield.spatial.unwrap()
        if destination_sdim.wrapped_state == WrappableCoordinateReferenceSystem._flag_wrapped:
            if sfield.spatial.wrapped_state == WrappableCoordinateReferenceSystem._flag_unwrapped:
                sfield.spatial = deepcopy(sfield.spatial)
                sfield.spatial.wrap()

        # remove the mask from the destination field.
        new_mask = np.zeros(destination_sdim.shape, dtype=bool)
        destination_sdim.set_mask(new_mask)

        # regrid the input fields.
        sfield = list(iter_regridded_fields([sfield], destination_sdim, **self.ops.regrid_options))[0]

        if regrid_required_update_crs:
            sfield.spatial.update_crs(original_sfield_crs)
        else:
            sfield.spatial.crs = original_sfield_crs

        # subset the output from the regrid operation as masked values may be introduced on the edges
        if subset_sdim_for_regridding is not None:
            ss = SpatialSubsetOperation(sfield)
            sfield = ss.get_spatial_subset('intersects', subset_sdim_for_regridding,
                                           use_spatial_index=env.USE_SPATIAL_INDEX,
                                           select_nearest=False)

        return sfield