def test_rectify_2x2_to_13x13_none(self): source_ds = self.new_2x2_dataset_with_irregular_coords() target_gm = GridMapping.regular(size=(13, 13), xy_min=(10.0, 50.0), xy_res=0.5, crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, target_gm=target_gm) self.assertIsNone(target_ds) target_gm = GridMapping.regular(size=(13, 13), xy_min=(-10.0, 50.0), xy_res=0.5, crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, target_gm=target_gm) self.assertIsNone(target_ds) target_gm = GridMapping.regular(size=(13, 13), xy_min=(0.0, 58.0), xy_res=0.5, crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, target_gm=target_gm) self.assertIsNone(target_ds) target_gm = GridMapping.regular(size=(13, 13), xy_min=(0.0, 42.0), xy_res=0.5, crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, target_gm=target_gm) self.assertIsNone(target_ds)
def test_rectify_dataset(self): source_ds = create_s2plus_dataset() expected_data = np.array([ [nan, nan, nan, nan, nan, nan, nan, nan, nan], [ nan, 0.019001, 0.019001, 0.008999, 0.012001, 0.012001, 0.022999, nan, nan ], [ nan, 0.021, 0.021, 0.009998, 0.009998, 0.008999, 0.022999, nan, nan ], [ nan, 0.022999, 0.022999, 0.007999, 0.007999, 0.008999, 0.023998, nan, nan ], [nan, 0.022999, 0.022999, 0.007, 0.007, 0.009998, 0.021, nan, nan], [nan, nan, nan, nan, nan, nan, nan, nan, nan] ]) source_gm = GridMapping.from_dataset(source_ds, prefer_crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, source_gm=source_gm, tile_size=None) self.assertEqual(None, target_ds.rrs_665.chunks) print(repr(target_ds.rrs_665.values)) np.testing.assert_almost_equal(target_ds.rrs_665.values, expected_data, decimal=3) target_ds = rectify_dataset(source_ds, source_gm=source_gm, tile_size=5) self.assertEqual(((5, 1), (5, 4)), target_ds.rrs_665.chunks) np.testing.assert_almost_equal(target_ds.rrs_665.values, expected_data, decimal=3) target_ds = rectify_dataset(source_ds, source_gm=source_gm, tile_size=None, is_j_axis_up=True) self.assertEqual(None, target_ds.rrs_665.chunks) np.testing.assert_almost_equal(target_ds.rrs_665.values, expected_data[::-1], decimal=3) target_ds = rectify_dataset(source_ds, source_gm=source_gm, tile_size=5, is_j_axis_up=True) self.assertEqual(((5, 1), (5, 4)), target_ds.rrs_665.chunks) np.testing.assert_almost_equal(target_ds.rrs_665.values, expected_data[::-1], decimal=3)
def test_rectify_2x2_to_7x7_subset(self): source_ds = self.new_2x2_dataset_with_irregular_coords() target_gm = GridMapping.regular(size=(7, 7), xy_min=(1.5, 50.5), xy_res=1.0, crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, target_gm=target_gm) lon, lat, rad = self._assert_shape_and_dim(target_ds, (7, 7)) np.testing.assert_almost_equal( lon.values, np.array([2.0, 3.0, 4.0, 5., 6., 7., 8.], dtype=lon.dtype)) np.testing.assert_almost_equal( lat.values, np.array([57., 56., 55., 54., 53., 52., 51.], dtype=lat.dtype)) np.testing.assert_almost_equal( rad.values, np.array([ [nan, nan, nan, nan, nan, nan, nan], [nan, nan, nan, nan, nan, nan, nan], [1.0, nan, nan, nan, nan, nan, nan], [1.0, 1.0, 2.0, nan, nan, nan, nan], [3.0, 1.0, 2.0, 2.0, 2.0, nan, nan], [3.0, 4.0, 2.0, nan, nan, nan, nan], [4.0, 4.0, nan, nan, nan, nan, nan], ], dtype=rad.dtype))
def test_rectify_2x2_to_13x13_output_ij_names(self): source_ds = self.new_2x2_dataset_with_irregular_coords() target_gm = GridMapping.regular(size=(13, 13), xy_min=(-0.25, 49.75), xy_res=0.5, crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, target_gm=target_gm, output_ij_names=('source_i', 'source_j')) lon, lat, rad, source_i, source_j = self._assert_shape_and_dim( target_ds, (13, 13), var_names=('rad', 'source_i', 'source_j')) np.testing.assert_almost_equal( lon.values, np.array([ 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5., 5.5, 6. ], dtype=lon.dtype)) np.testing.assert_almost_equal( lat.values, np.array([ 56., 55.5, 55., 54.5, 54., 53.5, 53., 52.5, 52., 51.5, 51., 50.5, 50. ], dtype=lat.dtype)) np.testing.assert_almost_equal(rad.values, self.expected_rad_13x13(rad.dtype)) np.testing.assert_almost_equal(np.floor(source_i.values + 0.5), self.expected_i_13x13()) np.testing.assert_almost_equal(np.floor(source_j.values + 0.5), self.expected_j_13x13())
def test_rectify_2x2_to_13x13_antimeridian(self): source_ds = self.new_2x2_dataset_with_irregular_coords_antimeridian() target_gm = GridMapping.regular(size=(13, 13), xy_min=(177.75, 49.75), xy_res=0.5, crs=CRS_WGS84) self.assertEqual(True, target_gm.is_lon_360) target_ds = rectify_dataset(source_ds, target_gm=target_gm) self.assertIsNotNone(target_ds) lon, lat, rad = self._assert_shape_and_dim(target_ds, (13, 13)) np.testing.assert_almost_equal( lon.values, np.array([ 178., 178.5, 179., 179.5, 180., -179.5, -179., -178.5, -178., -177.5, -177., -176.5, -176. ], dtype=lon.dtype)) np.testing.assert_almost_equal( lat.values, np.array([ 56., 55.5, 55., 54.5, 54., 53.5, 53., 52.5, 52., 51.5, 51., 50.5, 50. ], dtype=lat.dtype)) np.testing.assert_almost_equal(rad.values, self.expected_rad_13x13(rad.dtype))
def test_rectify_2x2_to_13x13_dask_13x3(self): source_ds = self.new_2x2_dataset_with_irregular_coords() target_gm = GridMapping.regular(size=(13, 13), xy_min=(-0.25, 49.75), xy_res=0.5, crs=CRS_WGS84, tile_size=(13, 3)) target_ds = rectify_dataset(source_ds, target_gm=target_gm) lon, lat, rad = self._assert_shape_and_dim(target_ds, (13, 13), chunks=((3, 3, 3, 3, 1), (13, ))) np.testing.assert_almost_equal( lon.values, np.array([ 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5., 5.5, 6. ], dtype=lon.dtype)) np.testing.assert_almost_equal( lat.values, np.array([ 56., 55.5, 55., 54.5, 54., 53.5, 53., 52.5, 52., 51.5, 51., 50.5, 50. ], dtype=lat.dtype)) np.testing.assert_almost_equal(rad.values, self.expected_rad_13x13(rad.dtype))
def test_rectify_2x2_to_default(self): source_ds = self.new_2x2_dataset_with_irregular_coords() target_gm = GridMapping.regular(size=(4, 4), xy_min=(-1, 49), xy_res=2, crs=CRS_WGS84) target_ds = rectify_dataset(source_ds, target_gm=target_gm) # target_ds = rectify_dataset(source_ds) rad = target_ds.rad # lon, lat, rad = self._assert_shape_and_dim(target_ds, (4, 4)) # np.testing.assert_almost_equal(lon.values, # np.array([0., 2., 4., 6.], # dtype=lon.dtype)) # np.testing.assert_almost_equal(lat.values, # np.array([56., 54., 52., 50.], # dtype=lat.dtype)) np.testing.assert_almost_equal( rad.values, np.array([[nan, nan, nan, nan], [nan, 1.0, 2.0, nan], [3.0, 3.0, 2.0, nan], [nan, 4.0, nan, nan]], dtype=rad.dtype))
def _rectify(input_path: str, xy_names: Optional[Tuple[str, str]], var_names: Optional[Sequence[str]], output_path: str, output_format: Optional[str], output_size: Optional[Tuple[int, int]], output_tile_size: Optional[Tuple[int, int]], output_point: Optional[Tuple[float, float]], output_res: Optional[float], output_crs: Optional[str], delta: float, dry_run: bool, monitor): import pyproj.crs from xcube.core.dsio import guess_dataset_format from xcube.core.dsio import open_dataset from xcube.core.dsio import write_dataset from xcube.core.gridmapping import GridMapping from xcube.core.resampling import rectify_dataset from xcube.core.sentinel3 import is_sentinel3_product from xcube.core.sentinel3 import open_sentinel3_product if not output_format: output_format = guess_dataset_format(output_path) output_gm = None output_gm_given = (output_size is not None, output_point is not None, output_res is not None, output_crs is not None) if all(output_gm_given): output_gm = GridMapping.regular(size=output_size, xy_min=output_point, xy_res=output_res, crs=pyproj.crs.CRS.from_user_input(output_crs)) elif any(output_gm_given): raise click.ClickException('SIZE, POINT, RES, and CRS must all be given or none of them.') monitor(f'Opening dataset from {input_path!r}...') if is_sentinel3_product(input_path): src_ds = open_sentinel3_product(input_path) else: src_ds = open_dataset(input_path) monitor('Rectifying...') rectified_ds = rectify_dataset(src_ds, xy_var_names=xy_names, var_names=var_names, target_gm=output_gm, tile_size=output_tile_size, uv_delta=delta) if rectified_ds is None: monitor(f'Dataset {input_path} does not seem to have an intersection with bounding box') return monitor(f'Writing rectified dataset to {output_path!r}...') if not dry_run: write_dataset(rectified_ds, output_path, output_format) monitor(f'Done.')
def process(self, dataset: xr.Dataset, geo_coding: GridMapping, output_geom: GridMapping, output_resampling: str, include_non_spatial_vars=False) -> xr.Dataset: """ Perform reprojection using tie-points / ground control points. """ reprojection_info = self.get_reprojection_info(dataset) warn_prefix = 'unsupported argument in np-GCP rectification mode' if reprojection_info.xy_crs is not None: warnings.warn( f'{warn_prefix}: ignoring ' f'reprojection_info.xy_crs = {reprojection_info.xy_crs!r}') if reprojection_info.xy_tp_names is not None: warnings.warn( f'{warn_prefix}: ignoring ' f'reprojection_info.xy_tp_names = {reprojection_info.xy_tp_names!r}' ) if reprojection_info.xy_gcp_step is not None: warnings.warn( f'{warn_prefix}: ignoring ' f'reprojection_info.xy_gcp_step = {reprojection_info.xy_gcp_step!r}' ) if reprojection_info.xy_tp_gcp_step is not None: warnings.warn( f'{warn_prefix}: ignoring ' f'reprojection_info.xy_tp_gcp_step = {reprojection_info.xy_tp_gcp_step!r}' ) if output_resampling != 'Nearest': warnings.warn(f'{warn_prefix}: ignoring ' f'dst_resampling = {output_resampling!r}') if include_non_spatial_vars: warnings.warn( f'{warn_prefix}: ignoring ' f'include_non_spatial_vars = {include_non_spatial_vars!r}') geo_coding = geo_coding.derive( xy_var_names=(reprojection_info.xy_names[0], reprojection_info.xy_names[1])) dataset = rectify_dataset(dataset, compute_subset=False, source_gm=geo_coding, target_gm=output_geom) if output_geom.is_tiled: # The following condition may become true, # if we have used rectified_dataset(input, ..., is_y_reverse=True) # In this case y-chunksizes will also be reversed. So that the first chunk is smaller than any other. # Zarr will reject such datasets, when written. if dataset.chunks.get('lat')[0] < dataset.chunks.get('lat')[-1]: dataset = dataset.chunk({ 'lat': output_geom.tile_height, 'lon': output_geom.tile_width }) if dataset is not None \ and geo_coding.crs.is_geographic \ and geo_coding.xy_var_names != ('lon', 'lat'): dataset = dataset.rename({ geo_coding.xy_var_names[0]: 'lon', geo_coding.xy_var_names[1]: 'lat' }) return dataset