Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix most warnings during tests #157

Merged
merged 9 commits into from
Dec 16, 2023
18 changes: 18 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,21 @@ build-backend = "setuptools.build_meta"
relative_files = true
plugins = ["Cython.Coverage"]
omit = ["trollimage/version.py", "versioneer.py"]

[tool.pytest.ini_options]
minversion = "6.0"
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
xfail_strict = true
filterwarnings = [
"error",
"ignore::rasterio.errors.NotGeoreferencedWarning",
# remove after #149 is merged
"ignore:invalid value encountered in cast:RuntimeWarning",
# dateutil needs a new release
# https://github.com/dateutil/dateutil/issues/1314
'ignore:datetime.datetime.utcfromtimestamp\(\) is deprecated and scheduled for removal:DeprecationWarning:dateutil',
]
log_cli_level = "info"
testpaths = [
"trollimage/tests",
]
7 changes: 0 additions & 7 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
[bdist_rpm]
requires=numpy python-pillow
release=1

[bdist_wheel]
universal=1

[flake8]
max-line-length = 120
exclude =
Expand Down
4 changes: 2 additions & 2 deletions trollimage/colormap.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,11 @@ def __init__(self, *tuples, **kwargs):
f"{self.values.shape[0]} and {self.colors.shape[0]}.")

def _validate_colors(self, colors):
colors = np.array(colors)
colors = np.asarray(colors)
if colors.ndim != 2 or colors.shape[-1] not in (3, 4):
raise ValueError("Colormap 'colors' must be RGB or RGBA. Got unexpected shape: {}".format(colors.shape))
if not np.issubdtype(colors.dtype, np.floating):
warnings.warn("Colormap 'colors' should be flotaing point numbers between 0 and 1.", stacklevel=3)
warnings.warn("Colormap 'colors' should be floating point numbers between 0 and 1.", stacklevel=3)
colors = colors.astype(np.float64)
return colors

Expand Down
53 changes: 30 additions & 23 deletions trollimage/tests/test_colormap.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,20 @@ def test_diff_colors_values(self):

def test_nonfloat_colors(self):
"""Pass integer colors to colormap."""
colormap.Colormap(
colors=np.arange(5 * 3, dtype=np.uint8).reshape((5, 3)),
values=np.linspace(0, 1, 5),
)
with pytest.warns(UserWarning, match="should be floating point"):
colormap.Colormap(
colors=np.arange(5 * 3, dtype=np.uint8).reshape((5, 3)),
values=np.linspace(0, 1, 5),
)

def test_merge_nonmonotonic(self):
"""Test that merged colormaps must have monotonic values."""
cmap1 = colormap.Colormap(
colors=np.arange(5 * 3).reshape((5, 3)),
colors=np.arange(5 * 3.0).reshape((5, 3)),
values=np.linspace(2, 3, 5),
)
cmap2 = colormap.Colormap(
colors=np.arange(5 * 3).reshape((5, 3)),
colors=np.arange(5 * 3.0).reshape((5, 3)),
values=np.linspace(0, 1, 5),
)
with pytest.raises(ValueError, match=r".*monotonic.*"):
Expand Down Expand Up @@ -274,11 +275,11 @@ def test_merge_rgb_rgba(self, colors1, colors2):
def test_merge_equal_values(self):
"""Test that merged colormaps can have equal values at the merge point."""
cmap1 = colormap.Colormap(
colors=np.arange(5 * 3).reshape((5, 3)),
colors=np.arange(5 * 3.0).reshape((5, 3)),
values=np.linspace(0, 1, 5),
)
cmap2 = colormap.Colormap(
colors=np.arange(5 * 3).reshape((5, 3)),
colors=np.arange(5 * 3.0).reshape((5, 3)),
values=np.linspace(1, 2, 5),
)
assert cmap1.values[-1] == cmap2.values[0]
Expand All @@ -288,11 +289,11 @@ def test_merge_equal_values(self):
def test_merge_monotonic_decreasing(self):
"""Test that merged colormaps can be monotonically decreasing."""
cmap1 = colormap.Colormap(
colors=np.arange(5 * 3).reshape((5, 3)),
colors=np.arange(5 * 3.0).reshape((5, 3)),
values=np.linspace(2, 1, 5),
)
cmap2 = colormap.Colormap(
colors=np.arange(5 * 3).reshape((5, 3)),
colors=np.arange(5 * 3.0).reshape((5, 3)),
values=np.linspace(1, 0, 5),
)
_assert_monotonic_values(cmap1, increasing=False)
Expand Down Expand Up @@ -557,7 +558,7 @@ def test_csv_roundtrip(self, tmp_path, csv_filename, new_range, color_scale):
else:
res = orig_cmap.to_csv(None, color_scale=color_scale)
assert isinstance(res, str)
new_cmap = colormap.Colormap.from_file(res, color_scale=color_scale)
new_cmap = colormap.Colormap.from_string(res, color_scale=color_scale)
np.testing.assert_allclose(orig_cmap.values, new_cmap.values)
np.testing.assert_allclose(orig_cmap.colors, new_cmap.colors)

Expand Down Expand Up @@ -636,23 +637,27 @@ def test_cmap_from_file_bad_shape(self):
with pytest.raises(ValueError):
colormap.Colormap.from_file(cmap_filename)

def test_cmap_from_np(self, tmp_path):
@pytest.mark.parametrize("color_scale", [None, 1.0])
def test_cmap_from_np(self, tmp_path, color_scale):
"""Test creating a colormap from a numpy file."""
cmap_data = _generate_cmap_test_data(None, "RGB")
cmap_data = _generate_cmap_test_data(color_scale, "RGB")
fnp = tmp_path / "test.npy"
np.save(fnp, cmap_data)
cmap = colormap.Colormap.from_np(fnp, color_scale=1)
cmap = colormap.Colormap.from_np(fnp, color_scale=color_scale or 255)
np.testing.assert_allclose(cmap.values, [0, 0.33333333, 0.6666667, 1])
np.testing.assert_array_equal(cmap.colors, cmap_data)
exp_data = cmap_data if color_scale == 1.0 else cmap_data / 255.0
np.testing.assert_array_equal(cmap.colors, exp_data)

def test_cmap_from_csv(self, tmp_path, color_scale=1):
@pytest.mark.parametrize("color_scale", [None, 1.0])
def test_cmap_from_csv(self, tmp_path, color_scale):
"""Test creating a colormap from a CSV file."""
cmap_data = _generate_cmap_test_data(None, "RGB")
cmap_data = _generate_cmap_test_data(color_scale, "RGB")
fnp = tmp_path / "test.csv"
np.savetxt(fnp, cmap_data, delimiter=",")
cmap = colormap.Colormap.from_csv(fnp, color_scale=1)
cmap = colormap.Colormap.from_csv(fnp, color_scale=color_scale or 255)
np.testing.assert_allclose(cmap.values, [0, 0.33333333, 0.66666667, 1])
np.testing.assert_array_equal(cmap.colors, cmap_data)
exp_data = cmap_data if color_scale == 1.0 else cmap_data / 255.0
np.testing.assert_array_equal(cmap.colors, exp_data)


def test_cmap_from_string():
Expand All @@ -663,12 +668,14 @@ def test_cmap_from_string():
np.testing.assert_array_equal(cmap.colors, [[0, 0, 0], [1, 1, 1], [2, 2, 2]])


def test_cmap_from_ndarray():
@pytest.mark.parametrize("color_scale", [None, 255, 1.0])
def test_cmap_from_ndarray(color_scale):
"""Test creating a colormap from a numpy array."""
cmap_data = _generate_cmap_test_data(None, "RGB")
cmap = colormap.Colormap.from_ndarray(cmap_data, color_scale=1)
cmap_data = _generate_cmap_test_data(color_scale, "RGB")
cmap = colormap.Colormap.from_ndarray(cmap_data, color_scale=color_scale or 255)
np.testing.assert_allclose(cmap.values, [0, 0.33333333, 0.66666667, 1])
np.testing.assert_array_equal(cmap.colors, cmap_data)
exp_data = cmap_data if color_scale == 1.0 else cmap_data / 255.0
np.testing.assert_array_equal(cmap.colors, exp_data)


def test_cmap_from_name():
Expand Down
72 changes: 35 additions & 37 deletions trollimage/tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import sys
import tempfile
import unittest
from datetime import timezone, datetime
from unittest import mock
from collections import OrderedDict
from tempfile import NamedTemporaryFile
Expand Down Expand Up @@ -935,7 +936,8 @@ def test_save_geotiff_float(self):

# with fill value
with NamedTemporaryFile(suffix='.tif') as tmp:
img.save(tmp.name, fill_value=128)
with pytest.warns(UserWarning, match="fill value will overlap with valid data"):
img.save(tmp.name, fill_value=128)
with rio.open(tmp.name) as f:
file_data = f.read()
assert file_data.shape == (3, 5, 5) # no alpha band
Expand Down Expand Up @@ -985,7 +987,8 @@ def test_save_geotiff_float(self):

# float input with fill value saved to int16 (signed!)
with NamedTemporaryFile(suffix='.tif') as tmp:
img.save(tmp.name, dtype=np.int16, fill_value=-128)
with pytest.warns(UserWarning, match="fill value will overlap with valid data"):
img.save(tmp.name, dtype=np.int16, fill_value=-128)
with rio.open(tmp.name) as f:
file_data = f.read()
assert file_data.shape == (3, 5, 5) # no alpha band
Expand Down Expand Up @@ -1031,8 +1034,6 @@ def test_save_geotiff_float(self):
reason="'NamedTemporaryFile' not supported on Windows")
def test_save_geotiff_datetime(self):
"""Test saving geotiffs when start_time is in the attributes."""
import datetime as dt

data = xr.DataArray(np.arange(75).reshape(5, 5, 3), dims=[
'y', 'x', 'bands'], coords={'bands': ['R', 'G', 'B']})

Expand All @@ -1042,7 +1043,7 @@ def test_save_geotiff_datetime(self):
assert "TIFFTAG_DATETIME" not in tags

# Valid datetime
data.attrs['start_time'] = dt.datetime.utcnow()
data.attrs['start_time'] = datetime.now(timezone.utc)
tags = _get_tags_after_writing_to_geotiff(data)
assert "TIFFTAG_DATETIME" in tags

Expand Down Expand Up @@ -1762,42 +1763,39 @@ def test_weber_fechner_stretch(self, dtype):
from trollimage import xrimage

arr = np.arange(75., dtype=dtype).reshape(5, 5, 3) / 74.
data = xr.DataArray(arr.copy(), dims=['y', 'x', 'bands'],
data = xr.DataArray(arr.copy() + 0.1, dims=['y', 'x', 'bands'],
coords={'bands': ['R', 'G', 'B']})
img = xrimage.XRImage(data)
img.stretch_weber_fechner(2.5, 0.2)
enhs = img.data.attrs['enhancement_history'][0]
assert enhs == {'weber_fechner': (2.5, 0.2)}
assert img.data.dtype == dtype
res = np.array([[[-np.inf, -6.73656795, -5.0037],
[-3.99003723, -3.27083205, -2.71297317],
[-2.25716928, -1.87179258, -1.5379641],
[-1.24350651, -0.98010522, -0.74182977],
[-0.52430133, -0.32419456, -0.13892463]],

[[0.03355755, 0.19490385, 0.34646541],
[0.48936144, 0.6245295, 0.75276273],
[0.87473814, 0.99103818, 1.10216759],
[1.20856662, 1.31062161, 1.40867339],
[1.50302421, 1.59394332, 1.68167162]],

[[1.7664255, 1.84840006, 1.92777181],
[2.00470095, 2.07933336, 2.1518022],
[2.22222939, 2.29072683, 2.35739745],
[2.42233616, 2.48563068, 2.54736221],
[2.60760609, 2.66643234, 2.72390613]],

[[2.78008827, 2.83503554, 2.88880105],
[2.94143458, 2.99298279, 3.04348956],
[3.09299613, 3.14154134, 3.18916183],
[3.23589216, 3.28176501, 3.32681127],
[3.37106022, 3.41453957, 3.45727566]],

[[3.49929345, 3.54061671, 3.58126801],
[3.62126886, 3.66063976, 3.69940022],
[3.7375689, 3.7751636, 3.81220131],
[3.84869831, 3.88467015, 3.92013174],
[3.95509735, 3.98958065, 4.02359478]]], dtype=dtype)
res = np.array([
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.0993509],
[0.25663552, 0.40460747, 0.54430866],
[0.6766145, 0.8022693, 0.92190945]],
[[1.0360844, 1.1452721, 1.2498899],
[1.350305, 1.446842, 1.5397894],
[1.629405, 1.7159187, 1.7995386],
[1.8804514, 1.9588281, 2.0348217],
[2.1085734, 2.1802118, 2.2498538]],
[[2.3176088, 2.3835757, 2.4478464],
[2.5105066, 2.571634, 2.631303],
[2.689581, 2.7465308, 2.8022122],
[2.8566809, 2.9099874, 2.9621818],
[3.013308, 3.0634098, 3.1125278]],
[[3.1606987, 3.207959, 3.2543423],
[3.299881, 3.344605, 3.3885431],
[3.431722, 3.4741676, 3.515905],
[3.5569568, 3.597345, 3.6370919],
[3.6762161, 3.714738, 3.7526748]],
[[3.7900448, 3.826864, 3.863149],
[3.8989153, 3.934177, 3.968948],
[4.0032415, 4.037072, 4.07045],
[4.103389, 4.135899, 4.1679916],
[4.199678, 4.2309675, 4.2618704]]], dtype=dtype)

np.testing.assert_allclose(img.data.values, res, atol=1.e-6)

Expand Down Expand Up @@ -2277,7 +2275,7 @@ def test_colorize_geotiff_tag(self, tmp_path, colormap_tag):
assert "colormap" not in metadata
else:
assert "colormap" in metadata
loaded_brbg = Colormap.from_file(metadata["colormap"])
loaded_brbg = Colormap.from_string(metadata["colormap"])
np.testing.assert_allclose(new_brbg.values, loaded_brbg.values)
np.testing.assert_allclose(new_brbg.colors, loaded_brbg.colors)

Expand Down Expand Up @@ -2466,7 +2464,7 @@ def test_palettize_geotiff_tag(self, tmp_path, colormap_tag, keep_palette):
assert "colormap" not in metadata
else:
assert "colormap" in metadata
loaded_brbg = Colormap.from_file(metadata["colormap"])
loaded_brbg = Colormap.from_string(metadata["colormap"])
np.testing.assert_allclose(new_brbg.values, loaded_brbg.values)
np.testing.assert_allclose(new_brbg.colors, loaded_brbg.colors)

Expand Down
5 changes: 3 additions & 2 deletions trollimage/xrimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -1240,11 +1240,12 @@ def stretch_weber_fechner(self, k, s0):

p = k.ln(S/S0)
p is perception, S is the stimulus, S0 is the stimulus threshold (the
highest unpercieved stimulus), and k is the factor.
highest unperceived stimulus), and k is the factor.

"""
attrs = self.data.attrs
self.data = k * np.log(self.data / s0)
clipped_stimuli = np.clip(self.data, s0, None)
self.data = k * np.log(clipped_stimuli / s0)
self.data.attrs = attrs
self.data.attrs.setdefault('enhancement_history', []).append({'weber_fechner': (k, s0)})

Expand Down
Loading