From 6ca41861c9cc30748774524fec5c1e25b2d55126 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut <1311787+PierreRaybaut@users.noreply.github.com> Date: Mon, 19 Oct 2026 20:45:49 +0200 Subject: [PATCH 1/2] test: domain images in physical coordinates, legacy creation parameters (#400) Sigima now displays the Gaussian, 2D ramp, sinusoidal grating, ring, Siemens star and 2D sinc images over their [xmin, xmax] x [ymin, ymax] domain. Tests relying on pixel coordinates (geometry transforms, analysis recompute) now request them explicitly, and a new test checks that creation parameters stored by earlier versions (object metadata and history) keep pixel coordinates when the image is recreated. Assisted-by: Claude Opus 5.5 --- .../auto_analysis_recompute_unit_test.py | 13 ++++-- .../common/creation_metadata_unit_test.py | 43 +++++++++++++++++++ .../image/geometry_transform_unit_test.py | 2 + 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/datalab/tests/features/common/auto_analysis_recompute_unit_test.py b/datalab/tests/features/common/auto_analysis_recompute_unit_test.py index df5251e47..dc910db42 100644 --- a/datalab/tests/features/common/auto_analysis_recompute_unit_test.py +++ b/datalab/tests/features/common/auto_analysis_recompute_unit_test.py @@ -54,9 +54,12 @@ def test_analysis_recompute_after_roi_change(): with datalab_test_app_context(console=False) as win: panel = win.imagepanel - # Create a 2D Gaussian image in a 200x200 image + # Create a 2D Gaussian image in a 200x200 image (pixel coordinates, as + # the ROIs and expected centroids below) size = 200 - param = Gauss2DParam.create(height=size, width=size, sigma=20) + param = Gauss2DParam.create( + height=size, width=size, sigma=20, physical_coords=False + ) img = create_image_from_param(param) panel.add_object(img) @@ -202,10 +205,12 @@ def test_analysis_recompute_after_recompute_1_to_1(): size = 200 # In Gauss2DParam, x0 and y0 are the center coordinates with Xmin=-10.0, # Ymin=-10.0, Xmax=10.0, Ymax=10.0 by default. - # The centroid position should be at (49.75, 99.5). + # The centroid position should be at (49.75, 99.5) in pixel coordinates. # After a 45° rotation, it should move closer to (64.32, 134.68). # Or after a 90° rotation, it should move to (99.5, 149.2). - param = Gauss2DParam.create(height=size, width=size, x0=-5.0) + param = Gauss2DParam.create( + height=size, width=size, x0=-5.0, physical_coords=False + ) img = create_image_from_param(param) panel.add_object(img) diff --git a/datalab/tests/features/common/creation_metadata_unit_test.py b/datalab/tests/features/common/creation_metadata_unit_test.py index ad9a16059..98c5e4b9b 100644 --- a/datalab/tests/features/common/creation_metadata_unit_test.py +++ b/datalab/tests/features/common/creation_metadata_unit_test.py @@ -14,10 +14,13 @@ PEAK_PARAMETERIZATION, GaussParam, SineParam, + SinusoidalGrating2DParam, + create_image, create_signal, ) from sigima.tools.signal.pulse import GaussianModel, LegacyPeakParameterizationError +from datalab.gui.creation import create_image_from_param from datalab.gui.newobject import ( CREATION_PARAMETERS_FORMAT_VERSION, CREATION_PARAMETERS_OPTION, @@ -26,6 +29,7 @@ extract_creation_parameters, insert_creation_parameters, ) +from datalab.history.core import decode_kwargs def _legacy_gaussian_json( @@ -117,3 +121,42 @@ def test_creation_parameter_formats_never_fall_back_implicitly() -> None: obj.set_metadata_option(LEGACY_CREATION_PARAMETERS_OPTION, _legacy_gaussian_json()) with pytest.raises(ValueError, match="Conflicting creation parameter formats"): extract_creation_parameters(obj) + + +def test_domain_image_creation_parameters_keep_their_coordinates() -> None: + """Images created before the "Physical coordinates" option stay in pixels. + + Recreating an image from creation parameters stored by DataLab 1.3 (without + the option) must give back the original pixel coordinates, while parameters + stored by this version are restored as they were. + """ + param = SinusoidalGrating2DParam.create(height=16, width=32) + image = create_image_from_param(param) + assert (image.x0, image.dx) == (param.xmin, (param.xmax - param.xmin) / 31) + restored = extract_creation_parameters(image) + assert isinstance(restored, SinusoidalGrating2DParam) + assert restored.physical_coords is True + + payload = json.loads(dataset_to_json(param)) + del payload["physical_coords"] + legacy = create_image("Legacy grating", np.zeros((16, 32))) + legacy.set_metadata_option( + CREATION_PARAMETERS_OPTION, + { + "format_version": CREATION_PARAMETERS_FORMAT_VERSION, + "dataset_json": json.dumps(payload), + }, + ) + legacy_param = extract_creation_parameters(legacy) + assert isinstance(legacy_param, SinusoidalGrating2DParam) + assert legacy_param.physical_coords is False + recreated = create_image_from_param(legacy_param) + assert (recreated.x0, recreated.y0, recreated.dx, recreated.dy) == ( + 0.0, + 0.0, + 1.0, + 1.0, + ) + + history_kwargs = decode_kwargs({"param": {"__dataset_json__": json.dumps(payload)}}) + assert history_kwargs["param"].physical_coords is False diff --git a/datalab/tests/features/image/geometry_transform_unit_test.py b/datalab/tests/features/image/geometry_transform_unit_test.py index c1b026789..fb329bf39 100644 --- a/datalab/tests/features/image/geometry_transform_unit_test.py +++ b/datalab/tests/features/image/geometry_transform_unit_test.py @@ -20,6 +20,7 @@ def __create_test_image() -> sio.ImageObj: """Create a test image with geometry results for testing.""" + # Geometry results and ROI below are defined in pixel coordinates param = sio.Gauss2DParam.create( height=600, width=600, @@ -27,6 +28,7 @@ def __create_test_image() -> sio.ImageObj: y0=7.5, title="Test image (with geometry results)", dtype=sio.ImageDatatypes.UINT16, + physical_coords=False, ) obj = sio.create_image_from_param(param) for geometry in test_data.generate_geometry_results(): From 77f701bc95f94ddaed9e90b31bb3dead9447483f Mon Sep 17 00:00:00 2001 From: Pierre Raybaut <1311787+PierreRaybaut@users.noreply.github.com> Date: Mon, 26 Oct 2026 15:38:32 +0100 Subject: [PATCH 2/2] build: require Sigima >= 1.3.0 Sigima 1.3.0 creates Gaussian, 2D ramp, sinusoidal grating, ring, Siemens star and 2D sinc images in physical coordinates. The tests ported from develop disable this through the new "physical_coords" option, which does not exist in Sigima 1.2.x: raise the minimum requirement accordingly (regenerated requirements.txt and doc/requirements.rst) and document it in the 1.3.1 release notes. Assisted-by: Claude Opus 5.5 --- .../fr/LC_MESSAGES/release_notes/release_1.03.po | 12 ++++++++++++ doc/release_notes/release_1.03.md | 8 ++++++++ doc/requirements.rst | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po index 780693c7f..7d82c1625 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po @@ -12,6 +12,18 @@ msgstr "" msgid "Version 1.3" msgstr "Version 1.3" +msgid "DataLab Version 1.3.1" +msgstr "DataLab Version 1.3.1" + +msgid "🔧 Improvements since version 1.3.0" +msgstr "🔧 Améliorations depuis la version 1.3.0" + +msgid "**Compatibility:**" +msgstr "**Compatibilité :**" + +msgid "Updated minimum Sigima requirement from 1.2.0 to 1.3.0: Gaussian, 2D ramp, sinusoidal grating, ring pattern, Siemens star and 2D sinc images are now created in physical coordinates (over their [xmin, xmax] × [ymin, ymax] domain) instead of pixel coordinates, unless the new \"Physical coordinates\" option is disabled. Images created with earlier versions keep their pixel coordinates when they are recreated" +msgstr "Mise à jour de la version minimale requise de Sigima de 1.2.0 à 1.3.0 : les images gaussienne, rampe 2D, réseau sinusoïdal, anneaux, étoile de Siemens et sinus cardinal 2D sont désormais créées en coordonnées physiques (sur leur domaine [xmin, xmax] × [ymin, ymax]) au lieu de coordonnées en pixels, sauf si la nouvelle option « Coordonnées physiques » est désactivée. Les images créées avec des versions antérieures conservent leurs coordonnées en pixels lorsqu'elles sont recréées" + msgid "DataLab Version 1.3.0" msgstr "DataLab Version 1.3.0" diff --git a/doc/release_notes/release_1.03.md b/doc/release_notes/release_1.03.md index a34b7176d..ee3271d5e 100644 --- a/doc/release_notes/release_1.03.md +++ b/doc/release_notes/release_1.03.md @@ -1,5 +1,13 @@ # Version 1.3 # +## DataLab Version 1.3.1 ## + +### 🔧 Improvements since version 1.3.0 ### + +**Compatibility:** + +* Updated minimum Sigima requirement from 1.2.0 to 1.3.0: Gaussian, 2D ramp, sinusoidal grating, ring pattern, Siemens star and 2D sinc images are now created in physical coordinates (over their [xmin, xmax] × [ymin, ymax] domain) instead of pixel coordinates, unless the new "Physical coordinates" option is disabled. Images created with earlier versions keep their pixel coordinates when they are recreated + ## DataLab Version 1.3.0 ## ### ✨ New Features ### diff --git a/doc/requirements.rst b/doc/requirements.rst index 1a69d6ff4..a75d48599 100644 --- a/doc/requirements.rst +++ b/doc/requirements.rst @@ -17,7 +17,7 @@ The `datalab-platform` package requires the following Python modules: - >= 2.11.0 - Curve and image plotting tools for Python/Qt applications * - Sigima - - >= 1.2.0 + - >= 1.3.0 - Scientific computing engine for 1D signals and 2D images, part of the DataLab open-source platform. * - SigimaX - >= 1.0.2 diff --git a/pyproject.toml b/pyproject.toml index f5a710aba..dea8d9c73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ requires-python = ">=3.9, <4" dependencies = [ "guidata >= 3.15.1", "PlotPy >= 2.11.0", - "Sigima >= 1.2.0", + "Sigima >= 1.3.0", "SigimaX >= 1.0.2", "NumPy >= 1.22, < 2.5", "SciPy >= 1.10.1, < 1.17", diff --git a/requirements.txt b/requirements.txt index e6320d3e8..cbe594606 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ PlotPy >= 2.11.0 PyQt5 >= 5.15.6 PyWavelets >= 1.2, < 2.0 SciPy >= 1.10.1, < 1.17 -Sigima >= 1.2.0 +Sigima >= 1.3.0 SigimaX >= 1.0.2 babel build