From b8d5c11ee9911a91e6aae6dba449991938591a83 Mon Sep 17 00:00:00 2001 From: matei jordache Date: Sat, 4 Apr 2026 23:14:17 -0700 Subject: [PATCH] simplify tests --- frontend/src/constants.ts | 24 ++--- .../fft_visual.py | 4 +- tests/node_tests/coordinate.py | 14 --- tests/node_tests/number.py | 10 --- tests/test_fft.py | 90 ------------------- 5 files changed, 14 insertions(+), 128 deletions(-) rename tests/test_fft_visual.py => scripts/fft_visual.py (95%) delete mode 100644 tests/node_tests/coordinate.py delete mode 100644 tests/node_tests/number.py diff --git a/frontend/src/constants.ts b/frontend/src/constants.ts index c8cb4d2..5a612a3 100644 --- a/frontend/src/constants.ts +++ b/frontend/src/constants.ts @@ -11,20 +11,20 @@ export const DATA_TYPES = new Set([ export const SOCKET_WIDGET_TYPES = new Set(['FLOAT', 'INT']); export const TYPE_COLORS: Record = { - DATA_FIELD: '#0800ff', - IMAGE: '#00ff08', + DATA_FIELD: '#7d8bdc', + IMAGE: '#69cc6c', LINE: '#ffb300', - RECORD_TABLE: '#ff0000', - DATA_TABLE: '#fbff00', - COORD: '#ea00ff', - COORDPAIR: '#f0cbff', - FLOAT: '#00bfff', - INT: '#ffffff', - ANNOTATION_SOURCE: '#00ffbf', - COLORMAP: '#000000', + RECORD_TABLE: '#cf6868', + DATA_TABLE: '#cbcd67', + COORD: '#bb65c2', + COORDPAIR: '#bababa', + FLOAT: '#76bcd4', + INT: '#cf8e8e', + ANNOTATION_SOURCE: '#79cab6', + COLORMAP: '#905454', MESH_MODEL: '#6e659e', - FONT: '#936991', - FILE_PATH: '#f1d19b', + FONT: '#cccf7f', + FILE_PATH: '#b87f7f', DIRECTORY: '#90d294', }; diff --git a/tests/test_fft_visual.py b/scripts/fft_visual.py similarity index 95% rename from tests/test_fft_visual.py rename to scripts/fft_visual.py index 38ff616..cc1129e 100644 --- a/tests/test_fft_visual.py +++ b/scripts/fft_visual.py @@ -2,7 +2,7 @@ Generate test images and their FFT outputs for visual comparison with Gwyddion. Saves PNG files to tests/output/. -Run: .venv/bin/python -m tests.test_fft_visual +Run from project root: .venv/bin/python scripts/fft_visual.py """ import sys import os @@ -12,7 +12,7 @@ sys.path.insert(0, ".") from backend.data_types import DataField, datafield_to_uint8, encode_preview from backend.nodes.fft_2d import FFT2D -OUT_DIR = os.path.join(os.path.dirname(__file__), "output") +OUT_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tests", "output") os.makedirs(OUT_DIR, exist_ok=True) diff --git a/tests/node_tests/coordinate.py b/tests/node_tests/coordinate.py deleted file mode 100644 index 3aa021a..0000000 --- a/tests/node_tests/coordinate.py +++ /dev/null @@ -1,14 +0,0 @@ -def test_coordinate(): - from backend.nodes.coordinate import Coordinate - - node = Coordinate() - - result = node.process(x=0.3, y=0.7) - assert len(result) == 1 - assert result[0] == (0.3, 0.7) - - result_zero = node.process(x=0.0, y=0.0) - assert result_zero[0] == (0.0, 0.0) - - result_one = node.process(x=1.0, y=1.0) - assert result_one[0] == (1.0, 1.0) diff --git a/tests/node_tests/number.py b/tests/node_tests/number.py deleted file mode 100644 index e3b4f91..0000000 --- a/tests/node_tests/number.py +++ /dev/null @@ -1,10 +0,0 @@ -def test_number(): - from backend.nodes.number import Number - - node = Number() - - result = node.process(value=1.25) - assert result == (1.25,) - - result_neg = node.process(value=-3.5) - assert result_neg == (-3.5,) diff --git a/tests/test_fft.py b/tests/test_fft.py index 633aff3..1d70ba2 100644 --- a/tests/test_fft.py +++ b/tests/test_fft.py @@ -10,7 +10,6 @@ import numpy as np sys.path.insert(0, ".") from backend.data_types import DataField from backend.nodes.fft_2d import FFT2D -from backend.nodes.fft_2d_inverse import FFT2DInverse def make_field(data, xreal=1e-6, yreal=1e-6): @@ -247,91 +246,6 @@ def test_log_magnitude_visual_range(): print(" PASS\n") -def test_inverse_fft_reconstructs_from_magnitude_and_phase(): - """Magnitude + phase from FFT2D should reconstruct the original image.""" - print("=== Test: Inverse FFT from magnitude + phase ===") - rng = np.random.default_rng(123) - data = rng.standard_normal((64, 96)) - field = make_field(data, xreal=2.4e-6, yreal=1.6e-6) - - fft_node = FFT2D() - ifft_node = FFT2DInverse() - - _, magnitude, phase, _ = fft_node.process(field, windowing="none", level="none") - reconstructed, = ifft_node.process(magnitude, representation="magnitude", phase=phase) - - max_err = np.max(np.abs(reconstructed.data - field.data)) - print(f" Reconstruction max error: {max_err:.3e}") - assert reconstructed.domain == "spatial" - assert reconstructed.data.shape == field.data.shape - assert np.isclose(reconstructed.xreal, field.xreal) - assert np.isclose(reconstructed.yreal, field.yreal) - assert max_err < 1e-9, f"Expected near-exact reconstruction, got {max_err}" - print(" PASS\n") - - -def test_inverse_fft_reconstructs_from_log_magnitude_and_phase(): - """log(|F|) + phase should also reconstruct after expm1 inversion.""" - print("=== Test: Inverse FFT from log magnitude + phase ===") - y, x = np.mgrid[0:72, 0:80] / 80.0 - data = ( - 0.8 * np.sin(2 * np.pi * 6 * x) - + 0.35 * np.cos(2 * np.pi * 9 * y) - + 0.15 * np.sin(2 * np.pi * (4 * x + 3 * y)) - ) - field = make_field(data, xreal=1.6e-6, yreal=1.44e-6) - - fft_node = FFT2D() - ifft_node = FFT2DInverse() - - log_magnitude, _, phase, _ = fft_node.process(field, windowing="none", level="none") - reconstructed, = ifft_node.process(log_magnitude, representation="log_magnitude", phase=phase) - - rms_err = np.sqrt(np.mean((reconstructed.data - field.data) ** 2)) - print(f" Reconstruction RMS error: {rms_err:.3e}") - assert rms_err < 1e-9, f"Expected near-exact reconstruction, got {rms_err}" - print(" PASS\n") - - -def test_inverse_fft_reconstructs_from_psdf_and_phase(): - """PSDF + phase should reconstruct after undoing PSDF scaling.""" - print("=== Test: Inverse FFT from PSDF + phase ===") - rng = np.random.default_rng(321) - data = rng.standard_normal((48, 64)) - field = make_field(data, xreal=3.2e-6, yreal=2.4e-6) - - fft_node = FFT2D() - ifft_node = FFT2DInverse() - - _, _, phase, psdf = fft_node.process(field, windowing="none", level="none") - reconstructed, = ifft_node.process(psdf, representation="psdf", phase=phase) - - max_err = np.max(np.abs(reconstructed.data - field.data)) - print(f" Reconstruction max error: {max_err:.3e}") - assert reconstructed.si_unit_z == field.si_unit_z - assert max_err < 1e-8, f"Expected near-exact reconstruction, got {max_err}" - print(" PASS\n") - - -def test_inverse_fft_zero_phase_mode_returns_valid_image(): - """Spectrum-only inversion should return a finite spatial image with the right shape.""" - print("=== Test: Inverse FFT zero-phase mode ===") - data = np.sin(2 * np.pi * 5 * np.mgrid[0:64, 0:64][1] / 64.0) - field = make_field(data, xreal=1e-6, yreal=1e-6) - - fft_node = FFT2D() - ifft_node = FFT2DInverse() - - _, magnitude, _, _ = fft_node.process(field, windowing="none", level="none") - reconstructed, = ifft_node.process(magnitude, representation="magnitude") - - print(f" Output shape: {reconstructed.data.shape}") - assert reconstructed.domain == "spatial" - assert reconstructed.data.shape == field.data.shape - assert np.all(np.isfinite(reconstructed.data)) - print(" PASS\n") - - if __name__ == "__main__": test_dc_removal() test_single_frequency() @@ -341,8 +255,4 @@ if __name__ == "__main__": test_plane_subtraction() test_non_square() test_log_magnitude_visual_range() - test_inverse_fft_reconstructs_from_magnitude_and_phase() - test_inverse_fft_reconstructs_from_log_magnitude_and_phase() - test_inverse_fft_reconstructs_from_psdf_and_phase() - test_inverse_fft_zero_phase_mode_returns_valid_image() print("All tests passed!")