Skip to content

Commit

Permalink
test_transform: clean code + handled pytest wng
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreRaybaut committed Oct 5, 2023
1 parent 96e2fce commit 3e2350b
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 67 deletions.
181 changes: 115 additions & 66 deletions plotpy/tests/gui/test_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,31 @@
import os

import numpy as np
import pytest
from guidata.env import execenv
from guidata.qthelpers import qt_app_context
from qtpy import QtCore as QC
from qtpy import QtGui as QG

from plotpy import io
from plotpy.builder import LUTAlpha, make
from plotpy.items import assemble_imageitems
from plotpy.items import TrImageItem, assemble_imageitems
from plotpy.tests import vistools as ptv
from plotpy.tests.data import gen_image4

DEFAULT_CHARS = "".join([chr(c) for c in range(32, 256)])


def get_font_array(sz, chars=DEFAULT_CHARS):
def get_font_array(sz: int, chars: str = DEFAULT_CHARS) -> np.ndarray | None:
"""Return array of font characters
Args:
sz: Font size
chars: Characters to include (default: all printable characters)
Returns:
Array of font characters
"""
font = QG.QFont()
font.setFixedPitch(True)
font.setPixelSize(sz)
Expand Down Expand Up @@ -61,7 +72,24 @@ def get_font_array(sz, chars=DEFAULT_CHARS):
return npy[:, :, 0]


def txtwrite(data, x, y, sz, txt, range=None):
def write_text_on_array(
data: np.ndarray,
x: int,
y: int,
sz: int,
txt: str,
range: tuple[int, int] | None = None,
) -> None:
"""Write text in image (in-place)
Args:
data: Image data
x: X-coordinate of top-left corner
y: Y-coordinate of top-left corner
sz: Font size
txt: Text to write
range: Range of values to map to 0-255 (default: None)
"""
arr = get_font_array(sz, txt)
if arr is None:
return
Expand All @@ -75,95 +103,116 @@ def txtwrite(data, x, y, sz, txt, range=None):
data[y : y + dy, x : x + dx] = arr


def get_bbox(items):
r = QC.QRectF()
for it in items:
r = r.united(it.boundingRect())
return r
def make_items(N: int) -> list[TrImageItem]:
"""Make test TrImageItem items
Args:
N: Image size (N x N)
Returns:
List of image items
"""
data = gen_image4(N, N)
m = data.min()
M = data.max()
items = [make.trimage(data, alpha_function=LUTAlpha.LINEAR, colormap="jet")]
for dtype in (np.uint8, np.uint16, np.int8, np.int16):
info = np.iinfo(dtype().dtype) # pylint: disable=no-value-for-parameter
s = float((info.max - info.min))
a1 = s * (data - m) / (M - m)
img = np.array(a1 + info.min, dtype)
write_text_on_array(img, 0, 0, int(N / 15.0), str(dtype))
items.append(make.trimage(img, colormap="jet"))
nc = int(np.sqrt(len(items)) + 1.0)
maxy, x, y = 0, 0, 0
w = None
for index, item in enumerate(items):
h = item.boundingRect().height()
if index % nc == 0:
x = 0
y += maxy
maxy = h
else:
x += w
maxy = max(maxy, h)
w = item.boundingRect().width()
item.set_transform(x, y, 0.0)
return items


def save_image(name: str, data: np.ndarray) -> None:
"""Save image to file
def save_image(name, data):
Args:
name: Base name of file
data: Image data
"""
for fname in (name + ".u16.tif", name + ".u8.png"):
if os.path.exists(fname):
os.remove(fname)
print(
"Saving image: {} x {} ({} KB):".format(
data.shape[0], data.shape[1], data.nbytes / 1024.0
)
)
size = int(data.nbytes / 1024.0)
print(f"Saving image: {data.shape[0]} x {data.shape[1]} ({size} KB):")
print(" --> uint16")
io.imwrite(name + ".u16.tif", data, dtype=np.uint16, max_range=True)
print(" --> uint8")
io.imwrite(name + ".u8.png", data, dtype=np.uint8, max_range=True)


def build_image(items):
def get_bbox(items: list[TrImageItem]) -> QC.QRectF:
"""Get bounding box of items
Args:
items: List of image items
Returns:
Bounding box of items
"""
rectf = QC.QRectF()
for item in items:
rectf = rectf.united(item.boundingRect())
return rectf


def build_image(items: list[TrImageItem]) -> None:
"""Build image from items
Args:
items: List of image items
"""
r = get_bbox(items)
x, y, w, h = r.getRect()
_x, _y, w, h = r.getRect()
print("-" * 80)
print("Assemble test1:", w, "x", h)
print(f"Assemble test1: {int(w)} x {int(h)}")
dest = assemble_imageitems(items, r, w, h)
if not execenv.unattended:
save_image("test1", dest)
print("-" * 80)
print("Assemble test2:", w / 4, "x", h / 4)
print(f"Assemble test1: {int(w/4)} x {int(h/4)}")
dest = assemble_imageitems(items, r, w / 4, h / 4)
if not execenv.unattended:
save_image("test2", dest)
print("-" * 80)


def test_transform():
"""Test"""
N = 500
data = gen_image4(N, N)
m = data.min()
M = data.max()
@pytest.mark.parametrize("assemble_images", [False, True])
def test_transform(N: int = 500, assemble_images: bool = False) -> None:
"""Test image transforms
Args:
N: Image size (N x N)
assemble_images: If True, assemble images (default: False)
"""
with qt_app_context(exec_loop=True):
items = [make.trimage(data, alpha_function=LUTAlpha.LINEAR, colormap="jet")]
for dtype in (np.uint8, np.uint16, np.int8, np.int16):
info = np.iinfo(dtype().dtype) # pylint: disable=no-value-for-parameter
s = float((info.max - info.min))
a1 = s * (data - m) / (M - m)
img = np.array(a1 + info.min, dtype)
txtwrite(img, 0, 0, int(N / 15.0), str(dtype))
items.append(make.trimage(img, colormap="jet"))
gridparam = make.gridparam(
background="black",
minor_enabled=(False, False),
major_style=(".", "gray", 1),
)
win = make.dialog(
edit=False,
toolbar=True,
items = make_items(N)
_win = ptv.show_items(
items,
wintitle="Transform test ({}x{} images)".format(N, N),
gridparam=gridparam,
type="image",
plot_type="image",
show_itemlist=False,
)
nc = int(np.sqrt(len(items)) + 1.0)
maxy, x, y = 0, 0, 0
w = None
plot = win.manager.get_plot()
for i, item in enumerate(items):
h = item.boundingRect().height()
if i % nc == 0:
x = 0
y += maxy
maxy = h
else:
x += w
maxy = max(maxy, h)
w = item.boundingRect().width()
item.set_transform(x, y, 0.0)
plot.add_item(item)
win.show()
return items


def test_build_image():
items = test_transform()
build_image(items)
if assemble_images:
build_image(items)


if __name__ == "__main__":
test_build_image()
test_transform(assemble_images=True)
3 changes: 2 additions & 1 deletion plotpy/tests/vistools.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def show_items(
auto_tools: bool = True,
lock_aspect_ratio: bool | None = None,
curve_antialiasing: bool | None = None,
show_itemlist: bool = True,
) -> PlotWindow:
"""Show plot items in a dialog box"""
win = make.dialog(
Expand All @@ -39,11 +40,11 @@ def show_items(
auto_tools=auto_tools,
lock_aspect_ratio=lock_aspect_ratio,
curve_antialiasing=curve_antialiasing,
show_itemlist=show_itemlist,
)
plot = win.manager.get_plot()
for item in items:
plot.add_item(item)
win.manager.get_itemlist_panel().show()
plot.set_items_readonly(False)
win.show()
return win

0 comments on commit 3e2350b

Please sign in to comment.