Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
# Conflicts:
#	HISTORY.rst
  • Loading branch information
danschef committed Aug 9, 2023
2 parents 134543c + 05131c2 commit e9878e1
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 199 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ History
* Fixed missing Polymer directory creation.
* Added hint about supported Polymer version to installation instructions.
* !90: Dropped Python 3.7 support and added 3.11 instead.
* !91: Implemented plain pytest assertions.
* Fixed warnings during PyPI packaging.


Expand Down
22 changes: 11 additions & 11 deletions tests/test_cli_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ def test_param_acceptance(self):
parsed_args = self.parser_run.parse_args(self.baseargs +
['--CPUs', '10'])
config = self.get_config(parsed_args)
self.assertEqual(config.CPUs, 10)
assert config.CPUs == 10

# test if parameter fallbacks are working ('CPUs' has a fallback)
parsed_args = self.parser_run.parse_args(self.baseargs)
config = self.get_config(parsed_args)

self.assertNotIsInstance(config.CPUs, str)
self.assertEqual(config.CPUs, cpu_count())
assert not isinstance(config.CPUs, str)
assert config.CPUs == cpu_count()

def test_param_list(self):
parsed_args = self.parser_run.parse_args(self.baseargs +
Expand All @@ -85,20 +85,20 @@ def test_param_boolean(self):
parsed_args = self.parser_run.parse_args(self.baseargs +
['--enable_ac', 'True'])
config = self.get_config(parsed_args)
self.assertIsInstance(config.enable_ac, bool)
self.assertEqual(config.enable_ac, True)
assert isinstance(config.enable_ac, bool)
assert config.enable_ac is True

parsed_args = self.parser_run.parse_args(self.baseargs +
['--enable_ac', 'false'])
config = self.get_config(parsed_args)
self.assertIsInstance(config.enable_ac, bool)
self.assertEqual(config.enable_ac, False)
assert isinstance(config.enable_ac, bool)
assert config.enable_ac is False

parsed_args = self.parser_run.parse_args(self.baseargs +
['--enable_ac', '0'])
config = self.get_config(parsed_args)
self.assertIsInstance(config.enable_ac, bool)
self.assertEqual(config.enable_ac, False)
assert isinstance(config.enable_ac, bool)
assert config.enable_ac is False

try:
self.parser_run.parse_args(self.baseargs + ['--enable_ac', 'treu'])
Expand All @@ -111,12 +111,12 @@ def test_json_opts(self):
parsed_args = self.parser_run.parse_args(
self.baseargs + ['--json_config', '{"general_opts": {"CPUs": 10}}'])
config = self.get_config(parsed_args)
self.assertEqual(config.CPUs, 10)
assert config.CPUs == 10

parsed_args = self.parser_run.parse_args(
self.baseargs + ['--json_config', '{"general_opts": {"CPUs": "None"}}'])
config = self.get_config(parsed_args)
self.assertEqual(config.CPUs, cpu_count())
assert config.CPUs == cpu_count()


if __name__ == '__main__':
Expand Down
32 changes: 16 additions & 16 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
dumps, \
JSONDecodeError

import pytest
from unittest import TestCase

from enpt.options.config import \
Expand All @@ -54,75 +55,74 @@
class Test_get_options(TestCase):
def test_target_is_file_no_validation(self):
opts_dict = get_options(os.path.join(path_options_default), validation=False)
self.assertIsInstance(opts_dict, dict)
assert isinstance(opts_dict, dict)

def test_target_is_file_validation(self):
opts_dict = get_options(os.path.join(path_options_default))
self.assertIsInstance(opts_dict, dict)
assert isinstance(opts_dict, dict)


class Test_EnPTConfig(TestCase):
def test_plain_args(self):
cfg = EnPTConfig(CPUs=10)
self.assertIsInstance(cfg, EnPTConfig)
self.assertTrue(cfg.CPUs == 10)
assert isinstance(cfg, EnPTConfig)
assert cfg.CPUs == 10

def test_jsonconfig_str_allfine(self):
cfg = '{"a": 1 /*comment*/, "b":2}'
cfg = EnPTConfig(json_config=cfg)
self.assertIsInstance(cfg, EnPTConfig)
assert isinstance(cfg, EnPTConfig)

def test_jsonconfig_str_nojson(self):
cfg = 'dict(a=1 /*comment*/, b=2)'
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
EnPTConfig(json_config=cfg)

def test_jsonconfig_str_badcomment(self):
cfg = '{"a": 1 /comment*/, "b":2}'
with self.assertWarns(UserWarning), self.assertRaises(JSONDecodeError):
with pytest.warns(UserWarning), pytest.raises(JSONDecodeError):
EnPTConfig(json_config=cfg)

def test_jsonconfig_str_undecodable_val(self):
cfg = '{"a": None /comment*/, "b":2}'
with self.assertWarns(UserWarning), self.assertRaises(JSONDecodeError):
with pytest.warns(UserWarning), pytest.raises(JSONDecodeError):
EnPTConfig(json_config=cfg)

def test_jsonconfig_str_schema_violation(self):
cfg = '{"general_opts": {"CPUs": "badvalue"}}'
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
EnPTConfig(json_config=cfg)

def test_jsonconfig_file(self):
cfg = os.path.join(path_options_default)
cfg = EnPTConfig(json_config=cfg)
self.assertIsInstance(cfg, EnPTConfig)
assert isinstance(cfg, EnPTConfig)

def test_jsonconfig_param_acceptance(self):
cfg = EnPTConfig(json_config='{"general_opts": {"CPUs": 10}}')
self.assertIsInstance(cfg, EnPTConfig)
self.assertTrue(cfg.CPUs == 10)
assert isinstance(cfg, EnPTConfig)
assert cfg.CPUs == 10

def test_to_jsonable_dict(self):
cfg = EnPTConfig()
jsonable_dict = cfg.to_jsonable_dict()
self.assertIsInstance(cfg.to_jsonable_dict(), dict)
assert isinstance(cfg.to_jsonable_dict(), dict)

# test if dict is jsonable
dumps(jsonable_dict)

def test_to_dict_validity(self):
cfg = EnPTConfig()
params = cfg.to_dict()
self.assertIsInstance(cfg.to_jsonable_dict(), dict)
assert isinstance(cfg.to_jsonable_dict(), dict)

# check validity
EnPTValidator(allow_unknown=True, schema=enpt_schema_config_output).validate(params)

def test_invalid_filepath(self):
with self.assertRaises(FileNotFoundError):
with pytest.raises(FileNotFoundError):
EnPTConfig(path_l1b_enmap_image='/path/to/not/existing/image.tif')


if __name__ == '__main__':
import pytest
pytest.main()
13 changes: 6 additions & 7 deletions tests/test_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,19 @@ def tearDown(self):
def test_run_all_processors(self):
self.CTR.run_all_processors()

self.assertTrue(glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_LOGFB.TIF')))
self.assertTrue(glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_BITMASK.TIF')))
self.assertTrue(glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_LOGCHL.TIF')))
self.assertTrue(glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_RGLI.TIF')))
self.assertTrue(glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_RNIR.TIF')))
assert glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_LOGFB.TIF'))
assert glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_BITMASK.TIF'))
assert glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_LOGCHL.TIF'))
assert glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_RGLI.TIF'))
assert glob(os.path.join(self.CTR.cfg.output_dir, '*', 'ENMAP01*-ACOUT_POLYMER_RNIR.TIF'))
# TODO: validate pixel values

@patch('acwater.acwater.polymer_ac_enmap', None)
def test_run_all_processors_without_acwater_installed(self):
"""Test to run all processors while replacing polymer_ac_enmap with None using mock.patch."""
self.CTR.run_all_processors()

self.assertTrue("As a fallback, SICOR is applied to water surfaces instead."
in self.CTR.L1_obj.logger.captured_stream)
assert "As a fallback, SICOR is applied to water surfaces instead." in self.CTR.L1_obj.logger.captured_stream


if __name__ == '__main__':
Expand Down
63 changes: 32 additions & 31 deletions tests/test_dead_pixel_correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
# with this program. If not, see <https://www.gnu.org/licenses/>.

from unittest import TestCase
import pytest

import numpy as np
from geoarray import GeoArray
Expand Down Expand Up @@ -68,17 +69,17 @@ def setUp(self):
self.deadpixelmap_3D = np.isnan(self.im)

def validate_output_spectral_interp(self, output):
self.assertIsInstance(output, (GeoArray, np.ndarray))
self.assertEqual(self.im.shape, output.shape)
self.assertNotEqual(np.mean(output[:, 0, 0]), 0) # first band, first column
self.assertNotEqual(np.mean(output[:, 2, 0]), 0) # first band, any column
self.assertNotEqual(np.mean(output[:, 2, 1]), 0) # second band, same column
self.assertNotEqual(np.mean(output[:, 4, 50]), 0) # 2 adjacent bands
self.assertNotEqual(np.mean(output[:, 4, 10]), 0) # 2 adjacent bands
self.assertNotEqual(np.mean(output[:, 20, 60]), 0) # single dead column
self.assertNotEqual(np.mean(output[:, 50, 86]), 0) # second last band, same column
self.assertNotEqual(np.mean(output[:, 50, 87]), 0) # last band, same column
self.assertNotEqual(np.mean(output[:, 2, 87]), 0) # single dead column, last band
assert isinstance(output, (GeoArray, np.ndarray))
assert self.im.shape == output.shape
assert np.mean(output[:, 0, 0]) != 0 # first band, first column
assert np.mean(output[:, 2, 0]) != 0 # first band, any column
assert np.mean(output[:, 2, 1]) != 0 # second band, same column
assert np.mean(output[:, 4, 50]) != 0 # 2 adjacent bands
assert np.mean(output[:, 4, 10]) != 0 # 2 adjacent bands
assert np.mean(output[:, 20, 60]) != 0 # single dead column
assert np.mean(output[:, 50, 86]) != 0 # second last band, same column
assert np.mean(output[:, 50, 87]) != 0 # last band, same column
assert np.mean(output[:, 2, 87]) != 0 # single dead column, last band

def test_correct_using_2D_deadpixelmap_spectral(self):
DPC = Dead_Pixel_Corrector(algorithm='spectral', interp_spectral='linear')
Expand Down Expand Up @@ -119,33 +120,33 @@ def get_data2d():
def test_axis_0(self):
data_int = interp_nodata_along_axis_2d(self.get_data2d(), axis=0, method='linear')
arr_exp = np.array([[0, 0, 2], [3, 5, 5], [6, 10, 8]])
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

mask_nodata = ~np.isfinite(self.get_data2d())
data_int = interp_nodata_along_axis_2d(self.get_data2d(), axis=0, nodata=mask_nodata, method='linear')
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

data_int = interp_nodata_along_axis_2d(self.get_data2d(), axis=0, method='linear', fill_value=-1)
arr_exp = np.array([[0, 0, 2], [3, 5, 5], [-1, 10, 8]])
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

def test_axis_1(self):
data_int = interp_nodata_along_axis_2d(self.get_data2d(), axis=1, method='linear')
arr_exp = np.array([[0, 0, 2], [3, 4, 5], [12, 10, 8]])
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

mask_nodata = ~np.isfinite(self.get_data2d())
data_int = interp_nodata_along_axis_2d(self.get_data2d(), axis=1, nodata=mask_nodata, method='linear')
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

data_int = interp_nodata_along_axis_2d(self.get_data2d(), axis=1, method='linear', fill_value=-1)
arr_exp = np.array([[0, 0, 2], [3, 4, 5], [-1, 10, 8]])
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

def test_bad_args(self):
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
interp_nodata_along_axis_2d(self.get_data2d(), axis=3)
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
interp_nodata_along_axis_2d(np.dstack([self.get_data2d(), self.get_data2d()]))


Expand All @@ -171,23 +172,23 @@ def test_3d_axis_0(self):
arr_exp[:, :, 0] = [[0, 0, 2], [3, 5, 5], [6, 10, 8]]
arr_exp[:, :, 1] = [[10, 10, 12], [13, 60, 15], [16, 110, 18]]
arr_exp[:, :, 2] = [[20, 20, 22], [23, 115, 25], [26, 210, 20]]
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

mask_nodata = ~np.isfinite(self.get_data3d())
data_int = interp_nodata_along_axis(self.get_data3d(), axis=0, nodata=mask_nodata, method='linear')
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

def test_3d_axis_1(self):
data_int = interp_nodata_along_axis(self.get_data3d(), axis=1, method='linear')
arr_exp = np.zeros((3, 3, 3))
arr_exp[:, :, 0] = [[0, 0, 2], [3, 4, 5], [12, 10, 8]]
arr_exp[:, :, 1] = [[10, 10, 12], [13, 14, 15], [16, 110, 204]]
arr_exp[:, :, 2] = [[20, 20, 22], [23, 24, 25], [400, 210, 20]]
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

mask_nodata = ~np.isfinite(self.get_data3d())
data_int = interp_nodata_along_axis(self.get_data3d(), axis=1, nodata=mask_nodata, method='linear')
self.assertTrue(np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int)
assert np.array_equal(data_int, arr_exp), 'Computed %s.' % data_int

def test_3d_axis_2(self):
data_int = interp_nodata_along_axis(self.get_data3d(), axis=2, method='linear')
Expand All @@ -203,12 +204,13 @@ def test_3d_axis_2(self):

def test_2d(self):
data_int = interp_nodata_along_axis(Test_interp_nodata_along_axis_2d.get_data2d())
self.assertTrue(np.array_equal(data_int, np.array([[0, 0, 2],
[3, 5, 5],
[6, 10, 8]])), 'Computed %s.' % data_int)
assert np.array_equal(data_int, np.array([[0, 0, 2],
[3, 5, 5],
[6, 10, 8]])), \
'Computed %s.' % data_int

def test_bad_args(self):
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
interp_nodata_along_axis(np.array([1, 2, 3]))


Expand Down Expand Up @@ -237,14 +239,13 @@ def test_interpolation_pandas(self):
np.testing.assert_array_equal(data_int_pandas, arr_exp_pandas, 'Computed %s.' % data_int_pandas)

def test_bad_args(self):
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
interp_nodata_spatially_2d(np.array([1, 2, 3]))
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
interp_nodata_spatially_2d(self.get_data2d(), nodata=np.array([1, 2, 3]))
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
interp_nodata_spatially_2d(self.get_data2d(), implementation='invalid')


if __name__ == '__main__':
import pytest
pytest.main()
16 changes: 8 additions & 8 deletions tests/test_dem_preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"""

from unittest import TestCase
import pytest

import numpy as np
from pyproj import CRS
Expand Down Expand Up @@ -65,17 +66,17 @@ def test_init_nomapinfo(self):
dem = GeoArray(np.array([1, 2]))

# no map info, no projection
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
DEM_Processor(dem, enmapIm_cornerCoords=self.ll_cornerCoords)

# no projection
dem.gt = (10.6, 0.00036, -0.0, 47.5, -0.0, -0.00036) # can be anything
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
DEM_Processor(dem, enmapIm_cornerCoords=self.ll_cornerCoords)

def test_init_noWGS84(self):
# NAD83 projection ({'proj': 'longlat', 'ellps': 'GRS80', 'towgs84': '0,0,0,0,0,0,0'})
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
dem = GeoArray(np.array([1, 2]),
geotransform=(10.6, 0.00036, -0.0, 47.5, -0.0, -0.00036), # can be anything
projection=CRS(4269).to_wkt()) # NAD83
Expand All @@ -87,14 +88,14 @@ def test_init_demTooSmall(self):
geotransform=(626938.928052, 30.0, 0, 5267203.56579, 0, -30.0),
projection=CRS(32632).to_wkt())

with self.assertRaises(ValueError):
with pytest.raises(ValueError):
DEM_Processor(dem, enmapIm_cornerCoords=self.ll_cornerCoords)

def test_get_flat_dem(self):
DP = DEM_Processor.get_flat_dem_from_average_elevation(corner_coords_lonlat=self.ll_cornerCoords,
average_elevation=50)
self.assertIsInstance(DP.dem, GeoArray)
self.assertEqual(np.mean(DP.dem), 50)
assert isinstance(DP.dem, GeoArray)
assert np.mean(DP.dem) == 50

def test_fill_gaps(self):
pass
Expand All @@ -108,9 +109,8 @@ def test_compute_aspect(self):
def test_to_sensor_geometry(self):
dem_sensor_geo = self.DP_mapgeo.to_sensor_geometry(lons=self.lons, lats=self.lats)

self.assertEqual(dem_sensor_geo.shape, (100, 1000))
assert dem_sensor_geo.shape == (100, 1000)


if __name__ == '__main__':
import pytest
pytest.main()
Loading

0 comments on commit e9878e1

Please sign in to comment.