File: binning_unit_test.py

package info (click to toggle)
python-sigima 1.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 25,608 kB
  • sloc: python: 35,251; makefile: 3
file content (125 lines) | stat: -rw-r--r-- 4,499 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.

"""
Image pixel binning computation test
"""

# pylint: disable=invalid-name  # Allows short reference names like x, y, ...
# pylint: disable=duplicate-code

import time

import numpy as np
import pytest
from numpy import ma

import sigima.params
import sigima.proc.image
from sigima.enums import BinningOperation
from sigima.tests import guiutils
from sigima.tests.data import get_test_image
from sigima.tests.env import execenv
from sigima.tools.image import binning


def compare_binning_images(data: ma.MaskedArray) -> None:
    """Compare binning images

    Args:
        data: Image data
    """
    # pylint: disable=import-outside-toplevel
    import sigima.viz.viz_plotpy as viz

    items = []
    items += [viz.create_image(data, interpolation="nearest")]
    # Computing pixel binning
    oa_t0 = time.time()
    for ix in range(1, 5):
        sx = 2**ix
        for iy in range(1, 5):
            sy = 2**iy
            for operation in BinningOperation:
                t0 = time.time()
                bdata = binning(data, sx=sx, sy=sy, operation=operation)
                title = f"[{sx}x{sy},{operation.value}]"
                item = viz.create_image(
                    bdata,
                    title=title,
                    interpolation="nearest",
                    xdata=[0, data.shape[1]],
                    ydata=[0, data.shape[0]],
                )
                item.hide()
                items.append(item)
                dt = time.time() - t0
                execenv.print(f"    {title}: {int(dt * 1e3):d} ms")
    oa_dt = time.time() - oa_t0
    execenv.print(f"    Overall calculation time: {int(oa_dt * 1e3):d} ms")
    viz.view_image_items(items, title="Binning test", show_itemlist=True)


@pytest.mark.gui
def test_binning_interactive() -> None:
    """Test binning computation and show results"""
    with guiutils.lazy_qt_app_context(force=True):
        data = get_test_image("*.scor-data").data[:500, :500]
        execenv.print(f"Data[dtype={data.dtype},shape={data.shape}]")
        compare_binning_images(data.view(ma.MaskedArray))


@pytest.mark.validation
def test_binning() -> None:
    """Validation test for binning computation"""
    # Implementation note:
    # ---------------------
    #
    # Pixel binning algorithm is validated graphically by comparing the results of
    # different binning operations and sizes: that is the purpose of the
    # `test_binning_graphically`` function.
    # Formal validation is not possible without reimplementation of the algorithm
    # here, which would be redundant and proove nothing. Instead, as a complementary
    # test, we only validate some basic properties of the binning algorithm:
    # - The output shape is correct
    # - The output data type is correct
    # - Some basic properties of the output data are correct (e.g. min, max, mean)

    src = get_test_image("*.scor-data")
    src.data = data = np.array(src.data[:500, :500], dtype=float)
    ny, nx = data.shape

    p = sigima.params.BinningParam()
    for operation in BinningOperation:
        p.operation = operation
        for sx in range(2, 3):
            for sy in range(2, 5):
                p.sx = sx
                p.sy = sy
                rdata = data[: ny - (ny % sy), : nx - (nx % sx)]
                dst = sigima.proc.image.binning(src, p)
                bdata = dst.data
                assert bdata.shape == (data.shape[0] // sy, data.shape[1] // sx)
                assert bdata.dtype == data.dtype
                if operation == "min":
                    assert bdata.min() == rdata.min()
                elif operation == "max":
                    assert bdata.max() == rdata.max()
                elif operation == "sum":
                    assert bdata.sum() == rdata.sum()
                elif operation == "average":
                    assert bdata.mean() == rdata.mean()
    for src_dtype in (float, np.uint8, np.uint16, np.int16):
        src.data = data = np.array(src.data[:500, :500], dtype=src_dtype)
        for dtype_str in p.dtypes:
            p.dtype_str = dtype_str
            dst = sigima.proc.image.binning(src, p)
            bdata = dst.data
            if dtype_str == "dtype":
                assert bdata.dtype is data.dtype
            else:
                assert bdata.dtype is np.dtype(dtype_str)


if __name__ == "__main__":
    test_binning_interactive()
    test_binning()