Skip to content

Commit 9ac72d6

Browse files
committed
Migrate unit tests from cdl to sigima_ (cont'd)
1 parent cc9a110 commit 9ac72d6

6 files changed

Lines changed: 118 additions & 47 deletions

File tree

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
22

33
"""
4-
Image offset correction unit test.
4+
Image background dialog unit test.
55
"""
66

77
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
@@ -10,22 +10,19 @@
1010

1111
from __future__ import annotations
1212

13-
import numpy as np
14-
import pytest
1513
from guidata.qthelpers import exec_dialog, qt_app_context
1614

1715
import sigima_.computation.image as sigima_image
1816
import sigima_.obj
1917
import sigima_.param
20-
from cdl.adapters_plotpy.factories import create_adapter_from_object
2118
from cdl.env import execenv
2219
from cdl.widgets.imagebackground import ImageBackgroundDialog
20+
from sigima_.tests import vistools
2321
from sigima_.tests.data import create_noisygauss_image
24-
from sigima_.tests.vistools import view_images_side_by_side
2522

2623

27-
def test_image_offset_correction_interactive() -> None:
28-
"""Image offset correction interactive test."""
24+
def test_image_background_dialog() -> None:
25+
"""Image background dialog test."""
2926
with qt_app_context():
3027
i1 = create_noisygauss_image()
3128
dlg = ImageBackgroundDialog(i1)
@@ -46,30 +43,12 @@ def test_image_offset_correction_interactive() -> None:
4643
param.x0, param.y0, param.dx, param.dy = ix0, iy0, ix1 - ix0, iy1 - iy0
4744
i2 = sigima_image.offset_correction(i1, param)
4845
i3 = sigima_image.clip(i2, sigima_.param.ClipParam.create(lower=0))
49-
view_images_side_by_side(
50-
[
51-
create_adapter_from_object(i1).make_item(),
52-
create_adapter_from_object(i3).make_item(),
53-
],
46+
vistools.view_images_side_by_side(
47+
[i1, i3],
5448
titles=["Original image", "Corrected image"],
5549
title="Image offset correction and thresholding",
5650
)
5751

5852

59-
@pytest.mark.validation
60-
def test_image_offset_correction() -> None:
61-
"""Image offset correction validation test."""
62-
i1 = create_noisygauss_image()
63-
param = sigima_.obj.ROI2DParam.create(x0=0, y0=0, dx=10, dy=10)
64-
i2 = sigima_image.offset_correction(i1, param)
65-
66-
# Check that the offset correction has been applied
67-
x0, y0 = param.x0, param.y0
68-
x1, y1 = x0 + param.dx, y0 + param.dy
69-
offset = np.mean(i1.data[y0:y1, x0:x1])
70-
assert np.allclose(i2.data, i1.data - offset), "Offset correction failed"
71-
72-
7353
if __name__ == "__main__":
74-
test_image_offset_correction_interactive()
75-
test_image_offset_correction()
54+
test_image_background_dialog()

cdl/tests/features/images/fft2d_unit_test.py renamed to cdl/tests/sigima_tests/images/fft2d_unit_test.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@
1616
import sigima_.obj
1717
import sigima_.param
1818
import sigima_.tests.data as ctd
19-
from cdl.env import execenv
19+
from sigima_.env import execenv
2020
from sigima_.tests.helpers import check_array_result, check_scalar_result
21-
from sigima_.tests.vistools import view_images_side_by_side
2221

2322

23+
@pytest.mark.gui
2424
def test_image_fft_interactive():
2525
"""2D FFT interactive test."""
2626
# pylint: disable=import-outside-toplevel
2727
from guidata.qthelpers import qt_app_context
2828

29+
from sigima_.tests import vistools
30+
2931
with qt_app_context():
3032
# Create a 2D ring image
3133
execenv.print("Generating 2D ring image...", end=" ")
@@ -45,7 +47,7 @@ def test_image_fft_interactive():
4547

4648
images = [data, f.real, f.imag, np.abs(f), data2.real, data2.imag]
4749
titles = ["Original", "Re(FFT)", "Im(FFT)", "Abs(FFT)", "Re(iFFT)", "Im(iFFT)"]
48-
view_images_side_by_side(images, titles, rows=2, title="2D FFT/iFFT")
50+
vistools.view_images_side_by_side(images, titles, rows=2, title="2D FFT/iFFT")
4951

5052

5153
@pytest.mark.validation

cdl/tests/features/images/hough_circle_unit_test.py renamed to cdl/tests/sigima_tests/images/hough_circle_unit_test.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,21 @@
99
# guitest: show
1010

1111
import numpy as np
12-
from guidata.qthelpers import qt_app_context
13-
from plotpy.builder import make
12+
import pytest
1413
from skimage.feature import canny
1514

16-
from cdl.env import execenv
1715
from sigima_.algorithms.image import get_hough_circle_peaks
16+
from sigima_.env import execenv
1817
from sigima_.tests.data import get_peak2d_data
19-
from sigima_.tests.vistools import view_image_items
2018

2119

2220
def __exec_hough_circle_test(data):
2321
"""Peak detection using circle Hough transform"""
22+
# pylint: disable=import-outside-toplevel
23+
from plotpy.builder import make
24+
25+
from sigima_.tests import vistools
26+
2427
edges = canny(
2528
data,
2629
sigma=30,
@@ -47,11 +50,15 @@ def __exec_hough_circle_test(data):
4750
xc, yc, r = shapeargs
4851
item = make.circle(xc - r, yc, xc + r, yc)
4952
items.append(item)
50-
view_image_items(items)
53+
vistools.view_image_items(items)
5154

5255

56+
@pytest.mark.gui
5357
def test_hough_circle():
5458
"""2D peak detection test"""
59+
# pylint: disable=import-outside-toplevel
60+
from guidata.qthelpers import qt_app_context
61+
5562
with qt_app_context():
5663
__exec_hough_circle_test(get_peak2d_data(multi=False))
5764

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2+
3+
"""
4+
Image offset correction unit test.
5+
"""
6+
7+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
8+
# pylint: disable=duplicate-code
9+
# guitest: show
10+
11+
from __future__ import annotations
12+
13+
import numpy as np
14+
import pytest
15+
16+
import sigima_.computation.image as sigima_image
17+
import sigima_.obj
18+
import sigima_.param
19+
from sigima_.tests.data import create_noisygauss_image
20+
21+
22+
@pytest.mark.gui
23+
def test_image_offset_correction_interactive() -> None:
24+
"""Image offset correction interactive test."""
25+
# pylint: disable=import-outside-toplevel
26+
from guidata.qthelpers import qt_app_context
27+
from plotpy.builder import make
28+
from plotpy.items import RectangleShape
29+
from plotpy.tools import RectangleTool
30+
from plotpy.widgets.selectdialog import SelectDialog, select_with_shape_tool
31+
32+
from sigima_.tests import vistools
33+
34+
with qt_app_context():
35+
i1 = create_noisygauss_image()
36+
shape: RectangleShape = select_with_shape_tool(
37+
None,
38+
RectangleTool,
39+
make.image(i1.data, interpolation="nearest", eliminate_outliers=1.0),
40+
"Select background area",
41+
tooldialogclass=SelectDialog,
42+
)
43+
if shape is not None:
44+
param = sigima_.obj.ROI2DParam()
45+
# pylint: disable=unbalanced-tuple-unpacking
46+
ix0, iy0, ix1, iy1 = i1.physical_to_indices(shape.get_rect())
47+
param.x0, param.y0, param.dx, param.dy = ix0, iy0, ix1 - ix0, iy1 - iy0
48+
i2 = sigima_image.offset_correction(i1, param)
49+
i3 = sigima_image.clip(i2, sigima_.param.ClipParam.create(lower=0))
50+
vistools.view_images_side_by_side(
51+
[i1, i3],
52+
titles=["Original image", "Corrected image"],
53+
title="Image offset correction and thresholding",
54+
)
55+
56+
57+
@pytest.mark.validation
58+
def test_image_offset_correction() -> None:
59+
"""Image offset correction validation test."""
60+
i1 = create_noisygauss_image()
61+
param = sigima_.obj.ROI2DParam.create(x0=0, y0=0, dx=10, dy=10)
62+
i2 = sigima_image.offset_correction(i1, param)
63+
64+
# Check that the offset correction has been applied
65+
x0, y0 = param.x0, param.y0
66+
x1, y1 = x0 + param.dx, y0 + param.dy
67+
offset = np.mean(i1.data[y0:y1, x0:x1])
68+
assert np.allclose(i2.data, i1.data - offset), "Offset correction failed"
69+
70+
71+
if __name__ == "__main__":
72+
test_image_offset_correction_interactive()
73+
test_image_offset_correction()

cdl/tests/features/images/operation_unit_test.py renamed to cdl/tests/sigima_tests/images/operation_unit_test.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,13 @@
1919
import numpy as np
2020
import pytest
2121
import scipy.ndimage as spi
22-
from guidata.qthelpers import qt_app_context
2322

2423
import sigima_.computation.image as sigima_image
2524
import sigima_.obj
2625
import sigima_.param
27-
from cdl.env import execenv
26+
from sigima_.env import execenv
2827
from sigima_.tests.data import create_noisygauss_image
2928
from sigima_.tests.helpers import check_array_result
30-
from sigima_.tests.vistools import view_images_side_by_side
3129

3230

3331
def __iterate_images() -> Generator[sigima_.obj.ImageObj, None, None]:
@@ -154,7 +152,7 @@ def test_image_product() -> None:
154152

155153

156154
@pytest.mark.validation
157-
def test_image_division() -> None:
155+
def test_image_division(request: pytest.FixtureRequest) -> None:
158156
"""Image division test."""
159157
execenv.print("*** Testing image division:")
160158
for ima1, ima2 in __iterate_image_couples():
@@ -164,10 +162,16 @@ def test_image_division() -> None:
164162
exp = ima1.data.astype(float) / ima2.data.astype(float)
165163
ima3 = sigima_image.division(ima1, ima2)
166164
if not np.allclose(ima3.data, exp):
167-
with qt_app_context():
168-
view_images_side_by_side(
169-
[ima1.data, ima2.data, ima3.data], ["ima1", "ima2", "ima3"]
170-
)
165+
if request.config.getoption("--gui"):
166+
# pylint: disable=import-outside-toplevel
167+
from guidata.qthelpers import qt_app_context
168+
169+
from sigima_.tests.vistools import view_images_side_by_side
170+
171+
with qt_app_context():
172+
view_images_side_by_side(
173+
[ima1.data, ima2.data, ima3.data], ["ima1", "ima2", "ima3"]
174+
)
171175
check_array_result("Image division", ima3.data, exp)
172176

173177

sigima_/tests/vistools.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ def __compute_grid(
299299

300300

301301
def view_images_side_by_side(
302-
images: list[ImageItem | np.ndarray],
302+
images: list[ImageItem | np.ndarray | ImageObj],
303303
titles: list[str],
304304
share_axes: bool = True,
305305
rows: int | None = None,
@@ -309,7 +309,7 @@ def view_images_side_by_side(
309309
"""Show sequence of images
310310
311311
Args:
312-
images: List of `ImageItem` or `np.ndarray` objects to display
312+
images: List of `ImageItem`, `np.ndarray`, or `ImageObj` objects to display
313313
titles: List of titles for each image
314314
share_axes: Whether to share axes across plots, default is True
315315
rows: Fixed number of rows in the grid, or None to compute automatically
@@ -326,7 +326,13 @@ def view_images_side_by_side(
326326
if isinstance(img, ImageItem):
327327
item = img
328328
else:
329-
item = make.image(img, interpolation="nearest", eliminate_outliers=0.1)
329+
if isinstance(img, ImageObj):
330+
data = img.data
331+
elif isinstance(img, np.ndarray):
332+
data = img
333+
else:
334+
raise TypeError(f"Unsupported image type: {type(img)}")
335+
item = make.image(data, interpolation="nearest", eliminate_outliers=0.1)
330336
plot.add_item(item)
331337
win.add_plot(row, col, plot, sync=share_axes)
332338
win.finalize_configuration()

0 commit comments

Comments
 (0)