From 8bd9b489a84fd4b3f3ec7c16a1f01c1746d57b8f Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 26 Nov 2021 17:30:49 +0100 Subject: [PATCH 1/7] Increased minimal version of pyresample to avoid ImportError. Signed-off-by: Daniel Scheffler --- HISTORY.rst | 6 ++++++ sensormapgeo/version.py | 4 ++-- setup.py | 2 +- tests/CI_docker/context/environment_sensormapgeo.yml | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index c6fd7bf..a82c4b4 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,12 @@ History ======= +0.6.1 (2021-11-26) +------------------ + +* Increased minimal version of pyresample to avoid ImportError. + + 0.6.0 (2021-11-26) ------------------ diff --git a/sensormapgeo/version.py b/sensormapgeo/version.py index 163e9c6..d324abb 100644 --- a/sensormapgeo/version.py +++ b/sensormapgeo/version.py @@ -24,6 +24,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = '0.6.0' -__versionalias__ = '20211126.01' +__version__ = '0.6.1' +__versionalias__ = '20211126.02' __author__ = 'Daniel Scheffler' diff --git a/setup.py b/setup.py index 49501b6..88277f3 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ version = {} with open("sensormapgeo/version.py") as version_file: exec(version_file.read(), version) -requirements = ['numpy', 'gdal', 'pyresample>=1.11.0', 'py_tools_ds>=0.18.0', 'pyproj>=2.2', 'pebble'] +requirements = ['numpy', 'gdal', 'pyresample>=1.17.0', 'py_tools_ds>=0.18.0', 'pyproj>=2.2', 'pebble'] setup_requirements = [] diff --git a/tests/CI_docker/context/environment_sensormapgeo.yml b/tests/CI_docker/context/environment_sensormapgeo.yml index 04230fe..7975df1 100644 --- a/tests/CI_docker/context/environment_sensormapgeo.yml +++ b/tests/CI_docker/context/environment_sensormapgeo.yml @@ -11,7 +11,7 @@ dependencies: - numpy - py-tools-ds>=0.18.0 - pyproj>=2.2 - - pyresample>=1.11.0 + - pyresample>=1.17.0 - pip: - pebble -- GitLab From ce8781b8ed15753f425f89953e144aac0fba4f3c Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 26 Nov 2021 20:37:52 +0100 Subject: [PATCH 2/7] Added subtests bases on pytest-subtests and converted Unittest assertions into raw assertions. Signed-off-by: Daniel Scheffler --- HISTORY.rst | 2 + setup.py | 2 +- .../context/environment_sensormapgeo.yml | 1 + tests/test_sensormapgeo.py | 341 +++++++++--------- 4 files changed, 184 insertions(+), 162 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index a82c4b4..3b479af 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,8 @@ History ------------------ * Increased minimal version of pyresample to avoid ImportError. +* Added subtests bases on pytest-subtests. +* Converted Unittest assertions into raw assertions (pytest-compatible). 0.6.0 (2021-11-26) diff --git a/setup.py b/setup.py index 88277f3..dec4c16 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ requirements = ['numpy', 'gdal', 'pyresample>=1.17.0', 'py_tools_ds>=0.18.0', 'p setup_requirements = [] -test_requirements = ['pytest', 'pytest-cov', 'pytest-reporter-html1', 'urlchecker'] +test_requirements = ['pytest', 'pytest-cov', 'pytest-reporter-html1', 'pytest-subtests', 'urlchecker'] setup( author="Daniel Scheffler", diff --git a/tests/CI_docker/context/environment_sensormapgeo.yml b/tests/CI_docker/context/environment_sensormapgeo.yml index 7975df1..4515b0f 100644 --- a/tests/CI_docker/context/environment_sensormapgeo.yml +++ b/tests/CI_docker/context/environment_sensormapgeo.yml @@ -23,6 +23,7 @@ dependencies: - pytest - pytest-cov - pytest-reporter-html1 + - pytest-subtests - sphinx-argparse - sphinx-autodoc-typehints - sphinx_rtd_theme diff --git a/tests/test_sensormapgeo.py b/tests/test_sensormapgeo.py index 0f5506c..889b032 100644 --- a/tests/test_sensormapgeo.py +++ b/tests/test_sensormapgeo.py @@ -73,98 +73,108 @@ class Test_SensorMapGeometryTransformer(TestCase): def test_to_sensor_geometry(self): for rsp_alg in rsp_algs: - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg, - radius_of_influence=30 if rsp_alg != 'bilinear' else 45) - kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) - if rsp_alg == 'bilinear': - with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): + with self.subTest(i=rsp_alg): + SMGT = SensorMapGeometryTransformer(lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg, + radius_of_influence=30 if rsp_alg != 'bilinear' else 45) + kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) + if rsp_alg == 'bilinear': + with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): + dem_sensor_geo = SMGT.to_sensor_geometry(self.dem_map_geo, **kw) + else: dem_sensor_geo = SMGT.to_sensor_geometry(self.dem_map_geo, **kw) - else: - dem_sensor_geo = SMGT.to_sensor_geometry(self.dem_map_geo, **kw) - self.assertIsInstance(dem_sensor_geo, np.ndarray) - self.assertFalse(np.array_equal(np.unique(dem_sensor_geo), np.array([0]))) - self.assertEqual(dem_sensor_geo.shape, (150, 1000)) - self.assertEqual(self.dem_map_geo.dtype, dem_sensor_geo.dtype) + assert isinstance(dem_sensor_geo, np.ndarray) + assert not np.array_equal(np.unique(dem_sensor_geo), np.array([0])) + assert dem_sensor_geo.shape == (150, 1000) + assert self.dem_map_geo.dtype == dem_sensor_geo.dtype def test_to_sensor_geometry_3DInput(self): for rsp_alg in rsp_algs: - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg) - dem_sensor_geo = SMGT.to_sensor_geometry(np.dstack([self.dem_map_geo] * 2), - src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) - self.assertIsInstance(dem_sensor_geo, np.ndarray) - self.assertFalse(np.array_equal(np.unique(dem_sensor_geo), np.array([0]))) - self.assertEqual(dem_sensor_geo.shape, (150, 1000, 2)) - self.assertTrue(np.array_equal(dem_sensor_geo[:, :, 0], dem_sensor_geo[:, :, 1])) - self.assertEqual(self.dem_map_geo.dtype, dem_sensor_geo.dtype) + with self.subTest(i=rsp_alg): + SMGT = SensorMapGeometryTransformer(lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg) + kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) + if rsp_alg == 'bilinear': + with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): + dem_sensor_geo = SMGT.to_sensor_geometry(np.dstack([self.dem_map_geo] * 2), **kw) + else: + dem_sensor_geo = SMGT.to_sensor_geometry(np.dstack([self.dem_map_geo] * 2), **kw) + + assert isinstance(dem_sensor_geo, np.ndarray) + assert not np.array_equal(np.unique(dem_sensor_geo), np.array([0])) + assert dem_sensor_geo.shape == (150, 1000, 2) + assert np.array_equal(dem_sensor_geo[:, :, 0], dem_sensor_geo[:, :, 1]) + assert self.dem_map_geo.dtype == dem_sensor_geo.dtype def test_to_map_geometry_lonlat(self): for rsp_alg in rsp_algs: - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg) - - # to Lon/Lat - dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, tgt_prj=4326) - - # from geoarray import GeoArray - # GeoArray(dem_map_geo, dem_gt, dem_prj)\ - # .save(os.path.join(tests_path, 'test_output', 'resampled_pyresample_ll.bsq')) - - self.assertIsInstance(dem_map_geo, np.ndarray) - self.assertEqual(dem_map_geo.shape, (SMGT.area_definition.height, - SMGT.area_definition.width)) - xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=dem_map_geo.shape[1], - rows=dem_map_geo.shape[0])) - self.assertTrue(False not in np.isclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_lonlat))) - self.assertFalse(np.array_equal(np.unique(dem_map_geo), np.array([0]))) - self.assertTrue(np.isclose(np.mean(dem_map_geo[dem_map_geo != 0]), - np.mean(self.dem_sensor_geo), - rtol=0.01)) - self.assertEqual(self.dem_sensor_geo.dtype, dem_map_geo.dtype) - - with self.assertRaises(ValueError): - SMGT.to_map_geometry(self.dem_sensor_geo[:10, :10], tgt_prj=4326) # must have the shape of lons/lats + with self.subTest(i=rsp_alg): + SMGT = SensorMapGeometryTransformer(lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg) + + # to Lon/Lat + dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, tgt_prj=4326) + + # from geoarray import GeoArray + # GeoArray(dem_map_geo, dem_gt, dem_prj)\ + # .save(os.path.join(tests_path, 'test_output', 'resampled_pyresample_ll.bsq')) + + assert isinstance(dem_map_geo, np.ndarray) + assert dem_map_geo.shape == (SMGT.area_definition.height, + SMGT.area_definition.width) + xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, + cols=dem_map_geo.shape[1], + rows=dem_map_geo.shape[0])) + assert np.allclose(np.array([xmin, ymin, xmax, ymax]), + np.array(self.expected_dem_area_extent_lonlat)) + assert not np.array_equal(np.unique(dem_map_geo), np.array([0])) + assert np.isclose(np.mean(dem_map_geo[dem_map_geo != 0]), + np.mean(self.dem_sensor_geo), + rtol=0.01) + assert self.dem_sensor_geo.dtype == dem_map_geo.dtype + + with self.assertRaises(ValueError): + SMGT.to_map_geometry(self.dem_sensor_geo[:10, :10], tgt_prj=4326) # must have shape of lons/lats def test_to_map_geometry_utm(self): for rsp_alg in rsp_algs: - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg, - # neighbours=8, - # radius_of_influence=45, - # epsilon=0 - ) - - # to UTM32 - # dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, tgt_prj=32632, tgt_res=(30, 30)) - dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, tgt_prj=32632, - tgt_res=(30, 30), - # tgt_extent=self.expected_dem_area_extent_utm, - tgt_coordgrid=((0, 30), (0, 30)) - ) - # from geoarray import GeoArray - # GeoArray(dem_map_geo, dem_gt, dem_prj).save(os.path.join(tests_path, 'test_output', - # 'resampled_pyresample_bilinear_16n.bsq')) - - self.assertIsInstance(dem_map_geo, np.ndarray) - self.assertEqual(dem_map_geo.shape, (366, 976)) - xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=dem_map_geo.shape[1], - rows=dem_map_geo.shape[0])) - self.assertTrue(False not in np.isclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_utm_ongrid))) - self.assertFalse(np.array_equal(np.unique(dem_map_geo), np.array([0]))) - self.assertTrue(np.isclose(np.mean(dem_map_geo[dem_map_geo != 0]), - np.mean(self.dem_sensor_geo), - rtol=0.01)) - self.assertEqual(self.dem_sensor_geo.dtype, dem_map_geo.dtype) + with self.subTest(i=rsp_alg): + SMGT = SensorMapGeometryTransformer(lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg, + # neighbours=8, + # radius_of_influence=45, + # epsilon=0 + ) + + # to UTM32 + # dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, + # tgt_prj=32632, tgt_res=(30, 30)) + dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, tgt_prj=32632, + tgt_res=(30, 30), + # tgt_extent=self.expected_dem_area_extent_utm, + tgt_coordgrid=((0, 30), (0, 30)) + ) + # from geoarray import GeoArray + # GeoArray(dem_map_geo, dem_gt, dem_prj).save(os.path.join(tests_path, 'test_output', + # 'resampled_pyresample_bilinear_16n.bsq')) + + assert isinstance(dem_map_geo, np.ndarray) + assert dem_map_geo.shape == (366, 976) + xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, + cols=dem_map_geo.shape[1], + rows=dem_map_geo.shape[0])) + assert np.allclose(np.array([xmin, ymin, xmax, ymax]), + np.array(self.expected_dem_area_extent_utm_ongrid)) + assert not np.array_equal(np.unique(dem_map_geo), np.array([0])) + assert np.isclose(np.mean(dem_map_geo[dem_map_geo != 0]), + np.mean(self.dem_sensor_geo), + rtol=0.01) + assert self.dem_sensor_geo.dtype == dem_map_geo.dtype class Test_SensorMapGeometryTransformer3D(TestCase): @@ -203,89 +213,98 @@ class Test_SensorMapGeometryTransformer3D(TestCase): def test_to_map_geometry_lonlat_3D_geolayer(self): for rsp_alg in rsp_algs: - for mp_alg in mp_algs: - SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, - lats=self.lats_3D, - # resamp_alg='nearest', - resamp_alg=rsp_alg, - mp_alg=mp_alg - ) - - # to Lon/Lat - data_mapgeo_3D, dem_gt, dem_prj = SMGT.to_map_geometry(self.data_sensor_geo_3D, tgt_prj=4326) - - # from geoarray import GeoArray - # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ - # .save(os.path.join(tests_path, 'test_output', 'resampled_3D_02_ll.bsq')) - - self.assertIsInstance(data_mapgeo_3D, np.ndarray) - # only validate number of bands (height and width are validated in 2D version - # fixed numbers may fail here due to float uncertainty errors - self.assertGreater(np.dot(*data_mapgeo_3D.shape[:2]), np.dot(*self.data_sensor_geo_3D.shape[:2])) - self.assertEqual(data_mapgeo_3D.shape[2], 2) - xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=data_mapgeo_3D.shape[1], - rows=data_mapgeo_3D.shape[0])) - self.assertTrue(False not in np.isclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_lonlat))) - - self.assertTrue(np.isclose(np.mean(data_mapgeo_3D[data_mapgeo_3D != 0]), - np.mean(self.data_sensor_geo_3D), - rtol=0.01)) - self.assertEqual(self.data_sensor_geo_3D.dtype, data_mapgeo_3D.dtype) + with self.subTest(i=rsp_alg): + for mp_alg in mp_algs: + with self.subTest(i=mp_alg): + SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, + lats=self.lats_3D, + # resamp_alg='nearest', + resamp_alg=rsp_alg, + mp_alg=mp_alg + ) + + # to Lon/Lat + data_mapgeo_3D, dem_gt, dem_prj = SMGT.to_map_geometry(self.data_sensor_geo_3D, tgt_prj=4326) + + # from geoarray import GeoArray + # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ + # .save(os.path.join(tests_path, 'test_output', 'resampled_3D_02_ll.bsq')) + + assert isinstance(data_mapgeo_3D, np.ndarray) + # only validate number of bands (height and width are validated in 2D version + # fixed numbers may fail here due to float uncertainty errors + assert np.dot(*data_mapgeo_3D.shape[:2]) > np.dot(*self.data_sensor_geo_3D.shape[:2]) + assert data_mapgeo_3D.shape[2] == 2 + xmin, xmax, ymin, ymax = \ + corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, + cols=data_mapgeo_3D.shape[1], + rows=data_mapgeo_3D.shape[0])) + assert np.allclose(np.array([xmin, ymin, xmax, ymax]), + np.array(self.expected_dem_area_extent_lonlat)) + + assert np.isclose(np.mean(data_mapgeo_3D[data_mapgeo_3D != 0]), + np.mean(self.data_sensor_geo_3D), + rtol=0.01) + assert self.data_sensor_geo_3D.dtype == data_mapgeo_3D.dtype def test_to_map_geometry_utm_3D_geolayer(self): for rsp_alg in rsp_algs: - for mp_alg in mp_algs: - SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, - lats=self.lats_3D, - # resamp_alg='nearest', - resamp_alg=rsp_alg, - mp_alg=mp_alg - ) - - # to Lon/Lat - data_mapgeo_3D, dem_gt, dem_prj = SMGT.to_map_geometry(self.data_sensor_geo_3D, - tgt_prj=32632, - tgt_res=(30, 30), - # tgt_extent=self.expected_dem_area_extent_utm, - tgt_coordgrid=((0, 30), (0, 30)) - ) - # from geoarray import GeoArray - # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ - # .save(os.path.join(tests_path, 'test_output', 'resampled_3D_02_pyresample.bsq')) - - self.assertIsInstance(data_mapgeo_3D, np.ndarray) - # only validate number of bands (height and width are validated in 2D version - # fixed numbers may fail here due to float uncertainty errors - self.assertGreater(np.dot(*data_mapgeo_3D.shape[:2]), np.dot(*self.data_sensor_geo_3D.shape[:2])) - self.assertEqual(data_mapgeo_3D.shape[2], 2) - xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=data_mapgeo_3D.shape[1], - rows=data_mapgeo_3D.shape[0])) - self.assertTrue(False not in np.isclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_utm_ongrid))) - - self.assertTrue(np.isclose(np.mean(data_mapgeo_3D[data_mapgeo_3D != 0]), - np.mean(self.data_sensor_geo_3D), - rtol=0.01)) - self.assertEqual(self.data_sensor_geo_3D.dtype, data_mapgeo_3D.dtype) + with self.subTest(i=rsp_alg): + for mp_alg in mp_algs: + with self.subTest(i=mp_alg): + SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, + lats=self.lats_3D, + # resamp_alg='nearest', + resamp_alg=rsp_alg, + mp_alg=mp_alg + ) + + # to Lon/Lat + data_mapgeo_3D, dem_gt, dem_prj = \ + SMGT.to_map_geometry(self.data_sensor_geo_3D, + tgt_prj=32632, + tgt_res=(30, 30), + # tgt_extent=self.expected_dem_area_extent_utm, + tgt_coordgrid=((0, 30), (0, 30)) + ) + # from geoarray import GeoArray + # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ + # .save(os.path.join(tests_path, 'test_output', 'resampled_3D_02_pyresample.bsq')) + + assert isinstance(data_mapgeo_3D, np.ndarray) + # only validate number of bands (height and width are validated in 2D version + # fixed numbers may fail here due to float uncertainty errors + assert np.dot(*data_mapgeo_3D.shape[:2]) > np.dot(*self.data_sensor_geo_3D.shape[:2]) + assert data_mapgeo_3D.shape[2] == 2 + xmin, xmax, ymin, ymax = \ + corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, + cols=data_mapgeo_3D.shape[1], + rows=data_mapgeo_3D.shape[0])) + assert np.allclose(np.array([xmin, ymin, xmax, ymax]), + np.array(self.expected_dem_area_extent_utm_ongrid)) + + assert np.isclose(np.mean(data_mapgeo_3D[data_mapgeo_3D != 0]), + np.mean(self.data_sensor_geo_3D), + rtol=0.01) + assert self.data_sensor_geo_3D.dtype == data_mapgeo_3D.dtype def test_to_sensor_geometry(self): for rsp_alg in rsp_algs: - for mp_alg in mp_algs: - SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, - lats=self.lats_3D, - resamp_alg=rsp_alg, - mp_alg=mp_alg - ) - kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) - if rsp_alg == 'bilinear': - with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): - dem_sensors_geo = SMGT.to_sensor_geometry(self.data_map_geo_3D, **kw) - else: - dem_sensors_geo = SMGT.to_sensor_geometry(self.data_map_geo_3D, **kw) - - self.assertIsInstance(dem_sensors_geo, np.ndarray) - self.assertEqual(dem_sensors_geo.shape, (150, 1000, 2)) - self.assertEqual(self.data_map_geo_3D.dtype, dem_sensors_geo.dtype) + with self.subTest(i=rsp_alg): + for mp_alg in mp_algs: + with self.subTest(i=mp_alg): + SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, + lats=self.lats_3D, + resamp_alg=rsp_alg, + mp_alg=mp_alg + ) + kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) + if rsp_alg == 'bilinear': + with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): + dem_sensors_geo = SMGT.to_sensor_geometry(self.data_map_geo_3D, **kw) + else: + dem_sensors_geo = SMGT.to_sensor_geometry(self.data_map_geo_3D, **kw) + + assert isinstance(dem_sensors_geo, np.ndarray) + assert dem_sensors_geo.shape == (150, 1000, 2) + assert self.data_map_geo_3D.dtype == dem_sensors_geo.dtype -- GitLab From 59bfa1bac7fcd29f88f8adb1807ad40d436b2a0f Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 26 Nov 2021 22:22:48 +0100 Subject: [PATCH 3/7] Refactored unittests to pytest. Signed-off-by: Daniel Scheffler --- HISTORY.rst | 2 +- tests/test_sensormapgeo.py | 353 ++++++++++++++++++++++--------------- 2 files changed, 207 insertions(+), 148 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 3b479af..f875b2b 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,8 +6,8 @@ History ------------------ * Increased minimal version of pyresample to avoid ImportError. +* Refactored unittests to pytest (new structure, raw assertions, ...). * Added subtests bases on pytest-subtests. -* Converted Unittest assertions into raw assertions (pytest-compatible). 0.6.0 (2021-11-26) diff --git a/tests/test_sensormapgeo.py b/tests/test_sensormapgeo.py index 889b032..39f6cb8 100644 --- a/tests/test_sensormapgeo.py +++ b/tests/test_sensormapgeo.py @@ -29,7 +29,6 @@ import os -from unittest import TestCase import pytest import numpy as np @@ -45,40 +44,50 @@ rsp_algs = ['nearest', 'bilinear', 'gauss'] mp_algs = ['bands', 'tiles'] -class Test_SensorMapGeometryTransformer(TestCase): - def setUp(self): - self.dem_map_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_map_geo.bsq')) - self.dem_sensor_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_sensor_geo.bsq')) - self.lons = LoadFile(os.path.join(tests_path, 'data', 'lons_full_vnir.bsq')) - self.lats = LoadFile(os.path.join(tests_path, 'data', 'lats_full_vnir.bsq')) - self.dem_area_extent_coarse_subset_utm = (622613.864409047, # LL_x - 5254111.40255343, # LL_x - 660473.864409047, # LL_x - 5269351.40255343) # UR_y - - self.expected_dem_area_extent_lonlat = (10.685733901515151, # LL_x - 47.44113415492957, # LL_y - 11.073066098484848, # UR_x - 47.54576584507042) # UR_y - - self.expected_dem_area_extent_utm = (626938.928052, # LL_x - 5256253.56579, # LL_y - 656188.928052, # UR_x - 5267203.56579) # UR_y - - self.expected_dem_area_extent_utm_ongrid = (626910, # LL_x - 5256240, # LL_y - 656190, # UR_x - 5267220) # UR_y - - def test_to_sensor_geometry(self): +class Test_SensorMapGeometryTransformer: + dem_map_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_map_geo.bsq')) + dem_sensor_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_sensor_geo.bsq')) + lons = LoadFile(os.path.join(tests_path, 'data', 'lons_full_vnir.bsq')) + lats = LoadFile(os.path.join(tests_path, 'data', 'lats_full_vnir.bsq')) + + dem_area_extent_coarse_subset_utm = ( + 622613.864409047, # LL_x + 5254111.40255343, # LL_x + 660473.864409047, # LL_x + 5269351.40255343 # UR_y + ) + expected_dem_area_extent_lonlat = ( + 10.685733901515151, # LL_x + 47.44113415492957, # LL_y + 11.073066098484848, # UR_x + 47.54576584507042 # UR_y + ) + expected_dem_area_extent_utm = ( + 626938.928052, # LL_x + 5256253.56579, # LL_y + 656188.928052, # UR_x + 5267203.56579 # UR_y + ) + expected_dem_area_extent_utm_ongrid = ( + 626910, # LL_x + 5256240, # LL_y + 656190, # UR_x + 5267220 # UR_y + ) + + def test_to_sensor_geometry(self, subtests): for rsp_alg in rsp_algs: - with self.subTest(i=rsp_alg): - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg, - radius_of_influence=30 if rsp_alg != 'bilinear' else 45) - kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) + + with subtests.test(i=rsp_alg): + SMGT = SensorMapGeometryTransformer( + lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg, + radius_of_influence=30 if rsp_alg != 'bilinear' else 45 + ) + kw = dict(src_prj=32632, + src_extent=self.dem_area_extent_coarse_subset_utm) + if rsp_alg == 'bilinear': with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): dem_sensor_geo = SMGT.to_sensor_geometry(self.dem_map_geo, **kw) @@ -90,13 +99,17 @@ class Test_SensorMapGeometryTransformer(TestCase): assert dem_sensor_geo.shape == (150, 1000) assert self.dem_map_geo.dtype == dem_sensor_geo.dtype - def test_to_sensor_geometry_3DInput(self): + def test_to_sensor_geometry_3DInput(self, subtests): for rsp_alg in rsp_algs: - with self.subTest(i=rsp_alg): - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg) - kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) + + with subtests.test(i=rsp_alg): + SMGT = SensorMapGeometryTransformer( + lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg + ) + kw = dict(src_prj=32632, + src_extent=self.dem_area_extent_coarse_subset_utm) if rsp_alg == 'bilinear': with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): dem_sensor_geo = SMGT.to_sensor_geometry(np.dstack([self.dem_map_geo] * 2), **kw) @@ -109,12 +122,15 @@ class Test_SensorMapGeometryTransformer(TestCase): assert np.array_equal(dem_sensor_geo[:, :, 0], dem_sensor_geo[:, :, 1]) assert self.dem_map_geo.dtype == dem_sensor_geo.dtype - def test_to_map_geometry_lonlat(self): + def test_to_map_geometry_lonlat(self, subtests): for rsp_alg in rsp_algs: - with self.subTest(i=rsp_alg): - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg) + + with subtests.test(i=rsp_alg): + SMGT = SensorMapGeometryTransformer( + lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg + ) # to Lon/Lat dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, tgt_prj=4326) @@ -126,9 +142,13 @@ class Test_SensorMapGeometryTransformer(TestCase): assert isinstance(dem_map_geo, np.ndarray) assert dem_map_geo.shape == (SMGT.area_definition.height, SMGT.area_definition.width) - xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=dem_map_geo.shape[1], - rows=dem_map_geo.shape[0])) + xmin, xmax, ymin, ymax = \ + corner_coord_to_minmax( + get_corner_coordinates( + gt=dem_gt, + cols=dem_map_geo.shape[1], + rows=dem_map_geo.shape[0]) + ) assert np.allclose(np.array([xmin, ymin, xmax, ymax]), np.array(self.expected_dem_area_extent_lonlat)) assert not np.array_equal(np.unique(dem_map_geo), np.array([0])) @@ -137,37 +157,51 @@ class Test_SensorMapGeometryTransformer(TestCase): rtol=0.01) assert self.dem_sensor_geo.dtype == dem_map_geo.dtype - with self.assertRaises(ValueError): - SMGT.to_map_geometry(self.dem_sensor_geo[:10, :10], tgt_prj=4326) # must have shape of lons/lats + with pytest.raises(ValueError): + SMGT.to_map_geometry(self.dem_sensor_geo[:10, :10], + tgt_prj=4326) # must have shape of lons/lats - def test_to_map_geometry_utm(self): + def test_to_map_geometry_utm(self, subtests): for rsp_alg in rsp_algs: - with self.subTest(i=rsp_alg): - SMGT = SensorMapGeometryTransformer(lons=self.lons, - lats=self.lats, - resamp_alg=rsp_alg, - # neighbours=8, - # radius_of_influence=45, - # epsilon=0 - ) + + with subtests.test(i=rsp_alg): + SMGT = SensorMapGeometryTransformer( + lons=self.lons, + lats=self.lats, + resamp_alg=rsp_alg, + # neighbours=8, + # radius_of_influence=45, + # epsilon=0 + ) # to UTM32 - # dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, - # tgt_prj=32632, tgt_res=(30, 30)) - dem_map_geo, dem_gt, dem_prj = SMGT.to_map_geometry(self.dem_sensor_geo, tgt_prj=32632, - tgt_res=(30, 30), - # tgt_extent=self.expected_dem_area_extent_utm, - tgt_coordgrid=((0, 30), (0, 30)) - ) + # dem_map_geo, dem_gt, dem_prj = \ + # SMGT.to_map_geometry( + # self.dem_sensor_geo, + # tgt_prj=32632, + # tgt_res=(30, 30) + # ) + dem_map_geo, dem_gt, dem_prj = \ + SMGT.to_map_geometry( + self.dem_sensor_geo, + tgt_prj=32632, + tgt_res=(30, 30), + # tgt_extent=self.expected_dem_area_extent_utm, + tgt_coordgrid=((0, 30), (0, 30)) + ) # from geoarray import GeoArray - # GeoArray(dem_map_geo, dem_gt, dem_prj).save(os.path.join(tests_path, 'test_output', - # 'resampled_pyresample_bilinear_16n.bsq')) + # GeoArray(dem_map_geo, dem_gt, dem_prj)\ + # .save(os.path.join(tests_path, 'test_output', 'resampled_pyresample_bilinear_16n.bsq')) assert isinstance(dem_map_geo, np.ndarray) assert dem_map_geo.shape == (366, 976) - xmin, xmax, ymin, ymax = corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=dem_map_geo.shape[1], - rows=dem_map_geo.shape[0])) + xmin, xmax, ymin, ymax = \ + corner_coord_to_minmax( + get_corner_coordinates( + gt=dem_gt, + cols=dem_map_geo.shape[1], + rows=dem_map_geo.shape[0]) + ) assert np.allclose(np.array([xmin, ymin, xmax, ymax]), np.array(self.expected_dem_area_extent_utm_ongrid)) assert not np.array_equal(np.unique(dem_map_geo), np.array([0])) @@ -177,54 +211,63 @@ class Test_SensorMapGeometryTransformer(TestCase): assert self.dem_sensor_geo.dtype == dem_map_geo.dtype -class Test_SensorMapGeometryTransformer3D(TestCase): - def setUp(self): - dem_map_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_map_geo.bsq')) - dem_sensor_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_sensor_geo.bsq')) - lons = LoadFile(os.path.join(tests_path, 'data', 'lons_full_vnir.bsq')) - lats = LoadFile(os.path.join(tests_path, 'data', 'lats_full_vnir.bsq')) - - self.data_map_geo_3D = np.dstack([dem_map_geo, dem_map_geo]) - self.data_sensor_geo_3D = np.dstack([dem_sensor_geo, dem_sensor_geo]) - self.lons_3D = np.dstack([lons, lons + .002]) # assume slightly different coordinates in both bands - self.lats_3D = np.dstack([lats, lats + .002]) - - self.dem_area_extent_coarse_subset_utm = (622613.864409047, # LL_x - 5254111.40255343, # LL_x - 660473.864409047, # LL_x - 5269351.40255343) # UR_y - - # this differs from the 2D version because the geolayer in the second band has slightly different coordinates - self.expected_dem_area_extent_lonlat = (10.685733901515151, # LL_x - 47.44113415492957, # LL_y - 11.075064739115845, # UR_x - 47.54772559829233) # UR_y - - self.expected_dem_area_extent_utm = (626938.928052, # LL_x - 5256253.56579, # LL_y - 656188.928052, # UR_x - 5267203.56579) # UR_y - - # this differs from the 2D version because the geolayer in the second band has slightly different coordinates - self.expected_dem_area_extent_utm_ongrid = (626910, # LL_x - 5256240, # LL_y - 656340, # UR_x - 5267430) # UR_y - - def test_to_map_geometry_lonlat_3D_geolayer(self): +class Test_SensorMapGeometryTransformer3D: + _dem_map_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_map_geo.bsq')) + _dem_sensor_geo = LoadFile(os.path.join(tests_path, 'data', 'dem_sensor_geo.bsq')) + _lons = LoadFile(os.path.join(tests_path, 'data', 'lons_full_vnir.bsq')) + _lats = LoadFile(os.path.join(tests_path, 'data', 'lats_full_vnir.bsq')) + + data_map_geo_3D = np.dstack([_dem_map_geo, _dem_map_geo]) + data_sensor_geo_3D = np.dstack([_dem_sensor_geo, _dem_sensor_geo]) + lons_3D = np.dstack([_lons, _lons + .002]) # assume slightly different coordinates in both bands + lats_3D = np.dstack([_lats, _lats + .002]) + dem_area_extent_coarse_subset_utm = ( + 622613.864409047, # LL_x + 5254111.40255343, # LL_x + 660473.864409047, # LL_x + 5269351.40255343 # UR_y + ) + # this differs from the 2D version because the geolayer in the second band has slightly different coordinates + expected_dem_area_extent_lonlat = ( + 10.685733901515151, # LL_x + 47.44113415492957, # LL_y + 11.075064739115845, # UR_x + 47.54772559829233 # UR_y + ) + expected_dem_area_extent_utm = ( + 626938.928052, # LL_x + 5256253.56579, # LL_y + 656188.928052, # UR_x + 5267203.56579 # UR_y + ) + # this differs from the 2D version because the geolayer in the second band has slightly different coordinates + expected_dem_area_extent_utm_ongrid = ( + 626910, # LL_x + 5256240, # LL_y + 656340, # UR_x + 5267430 # UR_y + ) + + def test_to_map_geometry_lonlat_3D_geolayer(self, subtests): for rsp_alg in rsp_algs: - with self.subTest(i=rsp_alg): + + with subtests.test(i=rsp_alg): for mp_alg in mp_algs: - with self.subTest(i=mp_alg): - SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, - lats=self.lats_3D, - # resamp_alg='nearest', - resamp_alg=rsp_alg, - mp_alg=mp_alg - ) + + with subtests.test(i=mp_alg): + SMGT = SensorMapGeometryTransformer3D( + lons=self.lons_3D, + lats=self.lats_3D, + # resamp_alg='nearest', + resamp_alg=rsp_alg, + mp_alg=mp_alg + ) # to Lon/Lat - data_mapgeo_3D, dem_gt, dem_prj = SMGT.to_map_geometry(self.data_sensor_geo_3D, tgt_prj=4326) + data_mapgeo_3D, dem_gt, dem_prj = \ + SMGT.to_map_geometry( + self.data_sensor_geo_3D, + tgt_prj=4326) # from geoarray import GeoArray # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ @@ -233,12 +276,16 @@ class Test_SensorMapGeometryTransformer3D(TestCase): assert isinstance(data_mapgeo_3D, np.ndarray) # only validate number of bands (height and width are validated in 2D version # fixed numbers may fail here due to float uncertainty errors - assert np.dot(*data_mapgeo_3D.shape[:2]) > np.dot(*self.data_sensor_geo_3D.shape[:2]) + assert np.dot(*data_mapgeo_3D.shape[:2]) >\ + np.dot(*self.data_sensor_geo_3D.shape[:2]) assert data_mapgeo_3D.shape[2] == 2 xmin, xmax, ymin, ymax = \ - corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=data_mapgeo_3D.shape[1], - rows=data_mapgeo_3D.shape[0])) + corner_coord_to_minmax( + get_corner_coordinates( + gt=dem_gt, + cols=data_mapgeo_3D.shape[1], + rows=data_mapgeo_3D.shape[0]) + ) assert np.allclose(np.array([xmin, ymin, xmax, ymax]), np.array(self.expected_dem_area_extent_lonlat)) @@ -247,26 +294,30 @@ class Test_SensorMapGeometryTransformer3D(TestCase): rtol=0.01) assert self.data_sensor_geo_3D.dtype == data_mapgeo_3D.dtype - def test_to_map_geometry_utm_3D_geolayer(self): + def test_to_map_geometry_utm_3D_geolayer(self, subtests): for rsp_alg in rsp_algs: - with self.subTest(i=rsp_alg): + + with subtests.test(i=rsp_alg): for mp_alg in mp_algs: - with self.subTest(i=mp_alg): - SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, - lats=self.lats_3D, - # resamp_alg='nearest', - resamp_alg=rsp_alg, - mp_alg=mp_alg - ) + + with subtests.test(i=mp_alg): + SMGT = SensorMapGeometryTransformer3D( + lons=self.lons_3D, + lats=self.lats_3D, + # resamp_alg='nearest', + resamp_alg=rsp_alg, + mp_alg=mp_alg + ) # to Lon/Lat data_mapgeo_3D, dem_gt, dem_prj = \ - SMGT.to_map_geometry(self.data_sensor_geo_3D, - tgt_prj=32632, - tgt_res=(30, 30), - # tgt_extent=self.expected_dem_area_extent_utm, - tgt_coordgrid=((0, 30), (0, 30)) - ) + SMGT.to_map_geometry( + self.data_sensor_geo_3D, + tgt_prj=32632, + tgt_res=(30, 30), + # tgt_extent=self.expected_dem_area_extent_utm, + tgt_coordgrid=((0, 30), (0, 30)) + ) # from geoarray import GeoArray # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ # .save(os.path.join(tests_path, 'test_output', 'resampled_3D_02_pyresample.bsq')) @@ -274,12 +325,16 @@ class Test_SensorMapGeometryTransformer3D(TestCase): assert isinstance(data_mapgeo_3D, np.ndarray) # only validate number of bands (height and width are validated in 2D version # fixed numbers may fail here due to float uncertainty errors - assert np.dot(*data_mapgeo_3D.shape[:2]) > np.dot(*self.data_sensor_geo_3D.shape[:2]) + assert np.dot(*data_mapgeo_3D.shape[:2]) > \ + np.dot(*self.data_sensor_geo_3D.shape[:2]) assert data_mapgeo_3D.shape[2] == 2 xmin, xmax, ymin, ymax = \ - corner_coord_to_minmax(get_corner_coordinates(gt=dem_gt, - cols=data_mapgeo_3D.shape[1], - rows=data_mapgeo_3D.shape[0])) + corner_coord_to_minmax( + get_corner_coordinates( + gt=dem_gt, + cols=data_mapgeo_3D.shape[1], + rows=data_mapgeo_3D.shape[0]) + ) assert np.allclose(np.array([xmin, ymin, xmax, ymax]), np.array(self.expected_dem_area_extent_utm_ongrid)) @@ -288,17 +343,21 @@ class Test_SensorMapGeometryTransformer3D(TestCase): rtol=0.01) assert self.data_sensor_geo_3D.dtype == data_mapgeo_3D.dtype - def test_to_sensor_geometry(self): + def test_to_sensor_geometry(self, subtests): for rsp_alg in rsp_algs: - with self.subTest(i=rsp_alg): + + with subtests.test(i=rsp_alg): for mp_alg in mp_algs: - with self.subTest(i=mp_alg): - SMGT = SensorMapGeometryTransformer3D(lons=self.lons_3D, - lats=self.lats_3D, - resamp_alg=rsp_alg, - mp_alg=mp_alg - ) - kw = dict(src_prj=32632, src_extent=self.dem_area_extent_coarse_subset_utm) + + with subtests.test(i=mp_alg): + SMGT = SensorMapGeometryTransformer3D( + lons=self.lons_3D, + lats=self.lats_3D, + resamp_alg=rsp_alg, + mp_alg=mp_alg + ) + kw = dict(src_prj=32632, + src_extent=self.dem_area_extent_coarse_subset_utm) if rsp_alg == 'bilinear': with pytest.warns(RuntimeWarning, match='Bilinear resampling is not available'): dem_sensors_geo = SMGT.to_sensor_geometry(self.data_map_geo_3D, **kw) -- GitLab From e7d507ae738b1a994b808b706d3de5f5bb530227 Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 26 Nov 2021 22:43:19 +0100 Subject: [PATCH 4/7] Simplified tests. Signed-off-by: Daniel Scheffler --- tests/test_sensormapgeo.py | 147 ++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 75 deletions(-) diff --git a/tests/test_sensormapgeo.py b/tests/test_sensormapgeo.py index 39f6cb8..c522824 100644 --- a/tests/test_sensormapgeo.py +++ b/tests/test_sensormapgeo.py @@ -139,23 +139,13 @@ class Test_SensorMapGeometryTransformer: # GeoArray(dem_map_geo, dem_gt, dem_prj)\ # .save(os.path.join(tests_path, 'test_output', 'resampled_pyresample_ll.bsq')) - assert isinstance(dem_map_geo, np.ndarray) - assert dem_map_geo.shape == (SMGT.area_definition.height, - SMGT.area_definition.width) - xmin, xmax, ymin, ymax = \ - corner_coord_to_minmax( - get_corner_coordinates( - gt=dem_gt, - cols=dem_map_geo.shape[1], - rows=dem_map_geo.shape[0]) - ) - assert np.allclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_lonlat)) - assert not np.array_equal(np.unique(dem_map_geo), np.array([0])) - assert np.isclose(np.mean(dem_map_geo[dem_map_geo != 0]), - np.mean(self.dem_sensor_geo), - rtol=0.01) - assert self.dem_sensor_geo.dtype == dem_map_geo.dtype + self.check_result_mapgeo( + dem_map_geo, + (SMGT.area_definition.height, + SMGT.area_definition.width), + self.expected_dem_area_extent_lonlat, + dem_gt + ) with pytest.raises(ValueError): SMGT.to_map_geometry(self.dem_sensor_geo[:10, :10], @@ -193,22 +183,32 @@ class Test_SensorMapGeometryTransformer: # GeoArray(dem_map_geo, dem_gt, dem_prj)\ # .save(os.path.join(tests_path, 'test_output', 'resampled_pyresample_bilinear_16n.bsq')) - assert isinstance(dem_map_geo, np.ndarray) - assert dem_map_geo.shape == (366, 976) - xmin, xmax, ymin, ymax = \ - corner_coord_to_minmax( - get_corner_coordinates( - gt=dem_gt, - cols=dem_map_geo.shape[1], - rows=dem_map_geo.shape[0]) - ) - assert np.allclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_utm_ongrid)) - assert not np.array_equal(np.unique(dem_map_geo), np.array([0])) - assert np.isclose(np.mean(dem_map_geo[dem_map_geo != 0]), - np.mean(self.dem_sensor_geo), - rtol=0.01) - assert self.dem_sensor_geo.dtype == dem_map_geo.dtype + self.check_result_mapgeo( + dem_map_geo, + (366, 976), + self.expected_dem_area_extent_utm_ongrid, + dem_gt + ) + + def check_result_mapgeo(self, dem_map_geo, expected_shape, expected_extent, dem_gt): + assert isinstance(dem_map_geo, np.ndarray) + assert dem_map_geo.shape == expected_shape + + xmin, xmax, ymin, ymax = \ + corner_coord_to_minmax( + get_corner_coordinates( + gt=dem_gt, + cols=dem_map_geo.shape[1], + rows=dem_map_geo.shape[0]) + ) + + assert np.allclose(np.array([xmin, ymin, xmax, ymax]), + np.array(expected_extent)) + assert not np.array_equal(np.unique(dem_map_geo), np.array([0])) + assert np.isclose(np.mean(dem_map_geo[dem_map_geo != 0]), + np.mean(self.dem_sensor_geo), + rtol=0.01) + assert self.dem_sensor_geo.dtype == dem_map_geo.dtype class Test_SensorMapGeometryTransformer3D: @@ -227,7 +227,8 @@ class Test_SensorMapGeometryTransformer3D: 660473.864409047, # LL_x 5269351.40255343 # UR_y ) - # this differs from the 2D version because the geolayer in the second band has slightly different coordinates + # this differs from the 2D version because the geolayer + # in the second band has slightly different coordinates expected_dem_area_extent_lonlat = ( 10.685733901515151, # LL_x 47.44113415492957, # LL_y @@ -240,7 +241,8 @@ class Test_SensorMapGeometryTransformer3D: 656188.928052, # UR_x 5267203.56579 # UR_y ) - # this differs from the 2D version because the geolayer in the second band has slightly different coordinates + # this differs from the 2D version because the geolayer + # in the second band has slightly different coordinates expected_dem_area_extent_utm_ongrid = ( 626910, # LL_x 5256240, # LL_y @@ -273,26 +275,11 @@ class Test_SensorMapGeometryTransformer3D: # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ # .save(os.path.join(tests_path, 'test_output', 'resampled_3D_02_ll.bsq')) - assert isinstance(data_mapgeo_3D, np.ndarray) - # only validate number of bands (height and width are validated in 2D version - # fixed numbers may fail here due to float uncertainty errors - assert np.dot(*data_mapgeo_3D.shape[:2]) >\ - np.dot(*self.data_sensor_geo_3D.shape[:2]) - assert data_mapgeo_3D.shape[2] == 2 - xmin, xmax, ymin, ymax = \ - corner_coord_to_minmax( - get_corner_coordinates( - gt=dem_gt, - cols=data_mapgeo_3D.shape[1], - rows=data_mapgeo_3D.shape[0]) - ) - assert np.allclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_lonlat)) - - assert np.isclose(np.mean(data_mapgeo_3D[data_mapgeo_3D != 0]), - np.mean(self.data_sensor_geo_3D), - rtol=0.01) - assert self.data_sensor_geo_3D.dtype == data_mapgeo_3D.dtype + self.check_result_mapgeo( + data_mapgeo_3D, + self.expected_dem_area_extent_lonlat, + dem_gt + ) def test_to_map_geometry_utm_3D_geolayer(self, subtests): for rsp_alg in rsp_algs: @@ -322,26 +309,11 @@ class Test_SensorMapGeometryTransformer3D: # GeoArray(data_mapgeo_3D, dem_gt, dem_prj)\ # .save(os.path.join(tests_path, 'test_output', 'resampled_3D_02_pyresample.bsq')) - assert isinstance(data_mapgeo_3D, np.ndarray) - # only validate number of bands (height and width are validated in 2D version - # fixed numbers may fail here due to float uncertainty errors - assert np.dot(*data_mapgeo_3D.shape[:2]) > \ - np.dot(*self.data_sensor_geo_3D.shape[:2]) - assert data_mapgeo_3D.shape[2] == 2 - xmin, xmax, ymin, ymax = \ - corner_coord_to_minmax( - get_corner_coordinates( - gt=dem_gt, - cols=data_mapgeo_3D.shape[1], - rows=data_mapgeo_3D.shape[0]) - ) - assert np.allclose(np.array([xmin, ymin, xmax, ymax]), - np.array(self.expected_dem_area_extent_utm_ongrid)) - - assert np.isclose(np.mean(data_mapgeo_3D[data_mapgeo_3D != 0]), - np.mean(self.data_sensor_geo_3D), - rtol=0.01) - assert self.data_sensor_geo_3D.dtype == data_mapgeo_3D.dtype + self.check_result_mapgeo( + data_mapgeo_3D, + self.expected_dem_area_extent_utm_ongrid, + dem_gt + ) def test_to_sensor_geometry(self, subtests): for rsp_alg in rsp_algs: @@ -367,3 +339,28 @@ class Test_SensorMapGeometryTransformer3D: assert isinstance(dem_sensors_geo, np.ndarray) assert dem_sensors_geo.shape == (150, 1000, 2) assert self.data_map_geo_3D.dtype == dem_sensors_geo.dtype + + def check_result_mapgeo(self, data_mapgeo_3D, expected_extent, dem_gt): + assert isinstance(data_mapgeo_3D, np.ndarray) + + # only validate number of bands (height and width are validated in 2D version + # fixed numbers may fail here due to float uncertainty errors + assert np.dot(*data_mapgeo_3D.shape[:2]) > \ + np.dot(*self.data_sensor_geo_3D.shape[:2]) + assert data_mapgeo_3D.shape[2] == 2 + + xmin, xmax, ymin, ymax = \ + corner_coord_to_minmax( + get_corner_coordinates( + gt=dem_gt, + cols=data_mapgeo_3D.shape[1], + rows=data_mapgeo_3D.shape[0]) + ) + + assert np.allclose(np.array([xmin, ymin, xmax, ymax]), + np.array(expected_extent)) + + assert np.isclose(np.mean(data_mapgeo_3D[data_mapgeo_3D != 0]), + np.mean(self.data_sensor_geo_3D), + rtol=0.01) + assert self.data_sensor_geo_3D.dtype == data_mapgeo_3D.dtype -- GitLab From 166c0ec63fade3d9b2a2fe42f18ee5612d7affec Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 26 Nov 2021 22:46:46 +0100 Subject: [PATCH 5/7] We need pytest-subtests. Signed-off-by: Daniel Scheffler --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 081d131..b9dcf47 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,7 +12,7 @@ test_sensormapgeo: script: - source /root/mambaforge/bin/activate ci_env - - pip install pytest pytest-cov pytest-reporter-html1 + - pip install pytest pytest-cov pytest-reporter-html1 pytest-subtests # run tests - make pytest -- GitLab From d179642e5d145435e11fbb20aa21b334c8dae513 Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 26 Nov 2021 22:57:28 +0100 Subject: [PATCH 6/7] Suppress pytest warning. Signed-off-by: Daniel Scheffler --- pytest.ini | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 pytest.ini diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..e81f8df --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +filterwarnings = + ignore:A private pytest class or function was used.:PytestDeprecationWarning -- GitLab From d98b264922122582a814cf4ba9ec7e97b0555d22 Mon Sep 17 00:00:00 2001 From: Daniel Scheffler Date: Fri, 26 Nov 2021 23:05:25 +0100 Subject: [PATCH 7/7] Don't set the category of the warning. Signed-off-by: Daniel Scheffler --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index e81f8df..0db43c9 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,3 @@ [pytest] filterwarnings = - ignore:A private pytest class or function was used.:PytestDeprecationWarning + ignore:A private pytest class or function was used. -- GitLab