datalab-platform 0.0.1.dev0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datalab/__init__.py +35 -2
- datalab/adapters_metadata/__init__.py +31 -0
- datalab/adapters_metadata/base_adapter.py +316 -0
- datalab/adapters_metadata/common.py +422 -0
- datalab/adapters_metadata/geometry_adapter.py +98 -0
- datalab/adapters_metadata/table_adapter.py +84 -0
- datalab/adapters_plotpy/__init__.py +54 -0
- datalab/adapters_plotpy/annotations.py +124 -0
- datalab/adapters_plotpy/base.py +110 -0
- datalab/adapters_plotpy/converters.py +86 -0
- datalab/adapters_plotpy/factories.py +80 -0
- datalab/adapters_plotpy/objects/__init__.py +0 -0
- datalab/adapters_plotpy/objects/base.py +197 -0
- datalab/adapters_plotpy/objects/image.py +157 -0
- datalab/adapters_plotpy/objects/scalar.py +565 -0
- datalab/adapters_plotpy/objects/signal.py +264 -0
- datalab/adapters_plotpy/roi/__init__.py +0 -0
- datalab/adapters_plotpy/roi/base.py +146 -0
- datalab/adapters_plotpy/roi/factory.py +93 -0
- datalab/adapters_plotpy/roi/image.py +207 -0
- datalab/adapters_plotpy/roi/signal.py +72 -0
- datalab/app.py +98 -0
- datalab/config.py +817 -0
- datalab/control/__init__.py +0 -0
- datalab/control/baseproxy.py +776 -0
- datalab/control/proxy.py +343 -0
- datalab/control/remote.py +1005 -0
- datalab/data/doc/DataLab_en.pdf +0 -0
- datalab/data/doc/DataLab_fr.pdf +0 -0
- datalab/data/icons/analysis/delete_results.svg +109 -0
- datalab/data/icons/analysis/fw1e2.svg +156 -0
- datalab/data/icons/analysis/fwhm.svg +156 -0
- datalab/data/icons/analysis/histogram.svg +49 -0
- datalab/data/icons/analysis/peak_detect.svg +160 -0
- datalab/data/icons/analysis/plot_results.svg +151 -0
- datalab/data/icons/analysis/show_results.svg +83 -0
- datalab/data/icons/analysis/stats.svg +49 -0
- datalab/data/icons/analysis.svg +120 -0
- datalab/data/icons/apply.svg +3 -0
- datalab/data/icons/check_all.svg +15 -0
- datalab/data/icons/collapse.svg +44 -0
- datalab/data/icons/collapse_selection.svg +63 -0
- datalab/data/icons/console.svg +101 -0
- datalab/data/icons/create/1d-normal.svg +8 -0
- datalab/data/icons/create/1d-poisson.svg +9 -0
- datalab/data/icons/create/1d-uniform.svg +8 -0
- datalab/data/icons/create/1d-zero.svg +57 -0
- datalab/data/icons/create/2d-gaussian.svg +56 -0
- datalab/data/icons/create/2d-normal.svg +38 -0
- datalab/data/icons/create/2d-poisson.svg +38 -0
- datalab/data/icons/create/2d-ramp.svg +90 -0
- datalab/data/icons/create/2d-sinc.svg +62 -0
- datalab/data/icons/create/2d-uniform.svg +38 -0
- datalab/data/icons/create/2d-zero.svg +13 -0
- datalab/data/icons/create/checkerboard.svg +39 -0
- datalab/data/icons/create/cosine.svg +12 -0
- datalab/data/icons/create/exponential.svg +55 -0
- datalab/data/icons/create/gaussian.svg +12 -0
- datalab/data/icons/create/grating.svg +29 -0
- datalab/data/icons/create/linear_chirp.svg +7 -0
- datalab/data/icons/create/logistic.svg +7 -0
- datalab/data/icons/create/lorentzian.svg +12 -0
- datalab/data/icons/create/planck.svg +12 -0
- datalab/data/icons/create/polynomial.svg +7 -0
- datalab/data/icons/create/pulse.svg +12 -0
- datalab/data/icons/create/ring.svg +18 -0
- datalab/data/icons/create/sawtooth.svg +7 -0
- datalab/data/icons/create/siemens.svg +35 -0
- datalab/data/icons/create/sinc.svg +12 -0
- datalab/data/icons/create/sine.svg +7 -0
- datalab/data/icons/create/square.svg +7 -0
- datalab/data/icons/create/square_pulse.svg +7 -0
- datalab/data/icons/create/step.svg +7 -0
- datalab/data/icons/create/step_pulse.svg +12 -0
- datalab/data/icons/create/triangle.svg +7 -0
- datalab/data/icons/create/voigt.svg +12 -0
- datalab/data/icons/edit/annotations.svg +72 -0
- datalab/data/icons/edit/annotations_copy.svg +114 -0
- datalab/data/icons/edit/annotations_delete.svg +83 -0
- datalab/data/icons/edit/annotations_edit.svg +98 -0
- datalab/data/icons/edit/annotations_export.svg +85 -0
- datalab/data/icons/edit/annotations_import.svg +85 -0
- datalab/data/icons/edit/annotations_paste.svg +100 -0
- datalab/data/icons/edit/copy_titles.svg +109 -0
- datalab/data/icons/edit/delete.svg +84 -0
- datalab/data/icons/edit/delete_all.svg +214 -0
- datalab/data/icons/edit/duplicate.svg +64 -0
- datalab/data/icons/edit/goto_source.svg +60 -0
- datalab/data/icons/edit/metadata.svg +60 -0
- datalab/data/icons/edit/metadata_add.svg +80 -0
- datalab/data/icons/edit/metadata_copy.svg +96 -0
- datalab/data/icons/edit/metadata_delete.svg +62 -0
- datalab/data/icons/edit/metadata_export.svg +68 -0
- datalab/data/icons/edit/metadata_import.svg +68 -0
- datalab/data/icons/edit/metadata_paste.svg +79 -0
- datalab/data/icons/edit/move_down.svg +55 -0
- datalab/data/icons/edit/move_up.svg +54 -0
- datalab/data/icons/edit/new_group.svg +76 -0
- datalab/data/icons/edit/recompute.svg +60 -0
- datalab/data/icons/edit/rename.svg +49 -0
- datalab/data/icons/edit.svg +16 -0
- datalab/data/icons/expand.svg +44 -0
- datalab/data/icons/expand_selection.svg +63 -0
- datalab/data/icons/fit/cdf_fit.svg +56 -0
- datalab/data/icons/fit/exponential_fit.svg +55 -0
- datalab/data/icons/fit/gaussian_fit.svg +62 -0
- datalab/data/icons/fit/interactive_fit.svg +101 -0
- datalab/data/icons/fit/linear_fit.svg +57 -0
- datalab/data/icons/fit/lorentzian_fit.svg +209 -0
- datalab/data/icons/fit/multigaussian_fit.svg +85 -0
- datalab/data/icons/fit/multilorentzian_fit.svg +85 -0
- datalab/data/icons/fit/piecewiseexponential_fit.svg +209 -0
- datalab/data/icons/fit/planckian_fit.svg +62 -0
- datalab/data/icons/fit/polynomial_fit.svg +59 -0
- datalab/data/icons/fit/sigmoid_fit.svg +56 -0
- datalab/data/icons/fit/sinusoidal_fit.svg +72 -0
- datalab/data/icons/fit/twohalfgaussian_fit.svg +63 -0
- datalab/data/icons/fit/voigt_fit.svg +57 -0
- datalab/data/icons/group.svg +56 -0
- datalab/data/icons/h5/h5array.svg +59 -0
- datalab/data/icons/h5/h5attrs.svg +75 -0
- datalab/data/icons/h5/h5browser.svg +133 -0
- datalab/data/icons/h5/h5file.svg +69 -0
- datalab/data/icons/h5/h5group.svg +49 -0
- datalab/data/icons/h5/h5scalar.svg +1 -0
- datalab/data/icons/help_pdf.svg +46 -0
- datalab/data/icons/history.svg +7 -0
- datalab/data/icons/image.svg +135 -0
- datalab/data/icons/io/fileopen_directory.svg +60 -0
- datalab/data/icons/io/fileopen_h5.svg +84 -0
- datalab/data/icons/io/fileopen_ima.svg +187 -0
- datalab/data/icons/io/fileopen_py.svg +123 -0
- datalab/data/icons/io/fileopen_sig.svg +138 -0
- datalab/data/icons/io/filesave_h5.svg +97 -0
- datalab/data/icons/io/filesave_ima.svg +200 -0
- datalab/data/icons/io/filesave_py.svg +136 -0
- datalab/data/icons/io/filesave_sig.svg +151 -0
- datalab/data/icons/io/import_text.svg +144 -0
- datalab/data/icons/io/save_to_directory.svg +134 -0
- datalab/data/icons/io.svg +84 -0
- datalab/data/icons/libre-camera-flash-off.svg +1 -0
- datalab/data/icons/libre-camera-flash-on.svg +1 -0
- datalab/data/icons/libre-gui-about.svg +1 -0
- datalab/data/icons/libre-gui-action-delete.svg +1 -0
- datalab/data/icons/libre-gui-add.svg +1 -0
- datalab/data/icons/libre-gui-arrow-down.svg +1 -0
- datalab/data/icons/libre-gui-arrow-left.svg +1 -0
- datalab/data/icons/libre-gui-arrow-right.svg +1 -0
- datalab/data/icons/libre-gui-arrow-up.svg +1 -0
- datalab/data/icons/libre-gui-close.svg +40 -0
- datalab/data/icons/libre-gui-cogs.svg +1 -0
- datalab/data/icons/libre-gui-globe.svg +1 -0
- datalab/data/icons/libre-gui-help.svg +1 -0
- datalab/data/icons/libre-gui-link.svg +1 -0
- datalab/data/icons/libre-gui-menu.svg +1 -0
- datalab/data/icons/libre-gui-pencil.svg +1 -0
- datalab/data/icons/libre-gui-plugin.svg +1 -0
- datalab/data/icons/libre-gui-questions.svg +1 -0
- datalab/data/icons/libre-gui-settings.svg +1 -0
- datalab/data/icons/libre-gui-unlink.svg +1 -0
- datalab/data/icons/libre-tech-ram.svg +1 -0
- datalab/data/icons/libre-toolbox.svg +1 -0
- datalab/data/icons/logs.svg +1 -0
- datalab/data/icons/markers.svg +74 -0
- datalab/data/icons/menu.svg +13 -0
- datalab/data/icons/new_ima.svg +148 -0
- datalab/data/icons/new_sig.svg +123 -0
- datalab/data/icons/operations/abs.svg +116 -0
- datalab/data/icons/operations/arithmetic.svg +123 -0
- datalab/data/icons/operations/average.svg +124 -0
- datalab/data/icons/operations/complex_from_magnitude_phase.svg +116 -0
- datalab/data/icons/operations/complex_from_real_imag.svg +124 -0
- datalab/data/icons/operations/constant.svg +116 -0
- datalab/data/icons/operations/constant_add.svg +109 -0
- datalab/data/icons/operations/constant_divide.svg +109 -0
- datalab/data/icons/operations/constant_multiply.svg +109 -0
- datalab/data/icons/operations/constant_subtract.svg +109 -0
- datalab/data/icons/operations/convert_dtype.svg +117 -0
- datalab/data/icons/operations/convolution.svg +46 -0
- datalab/data/icons/operations/deconvolution.svg +57 -0
- datalab/data/icons/operations/derivative.svg +127 -0
- datalab/data/icons/operations/difference.svg +52 -0
- datalab/data/icons/operations/division.svg +139 -0
- datalab/data/icons/operations/exp.svg +116 -0
- datalab/data/icons/operations/flip_horizontally.svg +69 -0
- datalab/data/icons/operations/flip_vertically.svg +74 -0
- datalab/data/icons/operations/im.svg +124 -0
- datalab/data/icons/operations/integral.svg +50 -0
- datalab/data/icons/operations/inverse.svg +143 -0
- datalab/data/icons/operations/log10.svg +109 -0
- datalab/data/icons/operations/phase.svg +116 -0
- datalab/data/icons/operations/power.svg +118 -0
- datalab/data/icons/operations/product.svg +124 -0
- datalab/data/icons/operations/profile.svg +379 -0
- datalab/data/icons/operations/profile_average.svg +399 -0
- datalab/data/icons/operations/profile_radial.svg +261 -0
- datalab/data/icons/operations/profile_segment.svg +262 -0
- datalab/data/icons/operations/quadratic_difference.svg +84 -0
- datalab/data/icons/operations/re.svg +124 -0
- datalab/data/icons/operations/rotate_left.svg +72 -0
- datalab/data/icons/operations/rotate_right.svg +72 -0
- datalab/data/icons/operations/signals_to_image.svg +314 -0
- datalab/data/icons/operations/sqrt.svg +110 -0
- datalab/data/icons/operations/std.svg +124 -0
- datalab/data/icons/operations/sum.svg +102 -0
- datalab/data/icons/play_demo.svg +9 -0
- datalab/data/icons/processing/axis_transform.svg +62 -0
- datalab/data/icons/processing/bandpass.svg +79 -0
- datalab/data/icons/processing/bandstop.svg +71 -0
- datalab/data/icons/processing/binning.svg +126 -0
- datalab/data/icons/processing/clip.svg +119 -0
- datalab/data/icons/processing/detrending.svg +173 -0
- datalab/data/icons/processing/distribute_on_grid.svg +769 -0
- datalab/data/icons/processing/edge_detection.svg +46 -0
- datalab/data/icons/processing/erase.svg +1 -0
- datalab/data/icons/processing/exposure.svg +143 -0
- datalab/data/icons/processing/fourier.svg +104 -0
- datalab/data/icons/processing/highpass.svg +59 -0
- datalab/data/icons/processing/interpolation.svg +71 -0
- datalab/data/icons/processing/level_adjustment.svg +70 -0
- datalab/data/icons/processing/lowpass.svg +60 -0
- datalab/data/icons/processing/morphology.svg +49 -0
- datalab/data/icons/processing/noise_addition.svg +114 -0
- datalab/data/icons/processing/noise_reduction.svg +38 -0
- datalab/data/icons/processing/normalize.svg +84 -0
- datalab/data/icons/processing/offset_correction.svg +131 -0
- datalab/data/icons/processing/resampling1d.svg +101 -0
- datalab/data/icons/processing/resampling2d.svg +240 -0
- datalab/data/icons/processing/reset_positions.svg +185 -0
- datalab/data/icons/processing/resize.svg +9 -0
- datalab/data/icons/processing/reverse_signal_x.svg +171 -0
- datalab/data/icons/processing/stability.svg +11 -0
- datalab/data/icons/processing/swap_x_y.svg +65 -0
- datalab/data/icons/processing/thresholding.svg +63 -0
- datalab/data/icons/processing/windowing.svg +45 -0
- datalab/data/icons/properties.svg +26 -0
- datalab/data/icons/reset.svg +9 -0
- datalab/data/icons/restore.svg +40 -0
- datalab/data/icons/roi/roi.svg +76 -0
- datalab/data/icons/roi/roi_coordinate.svg +78 -0
- datalab/data/icons/roi/roi_copy.svg +112 -0
- datalab/data/icons/roi/roi_delete.svg +81 -0
- datalab/data/icons/roi/roi_export.svg +87 -0
- datalab/data/icons/roi/roi_graphical.svg +78 -0
- datalab/data/icons/roi/roi_grid.svg +67 -0
- datalab/data/icons/roi/roi_ima.svg +188 -0
- datalab/data/icons/roi/roi_import.svg +87 -0
- datalab/data/icons/roi/roi_new.svg +81 -0
- datalab/data/icons/roi/roi_new_circle.svg +95 -0
- datalab/data/icons/roi/roi_new_polygon.svg +110 -0
- datalab/data/icons/roi/roi_new_rectangle.svg +70 -0
- datalab/data/icons/roi/roi_paste.svg +98 -0
- datalab/data/icons/roi/roi_sig.svg +124 -0
- datalab/data/icons/shapes.svg +134 -0
- datalab/data/icons/signal.svg +103 -0
- datalab/data/icons/table.svg +85 -0
- datalab/data/icons/table_unavailable.svg +102 -0
- datalab/data/icons/to_signal.svg +124 -0
- datalab/data/icons/tour/next.svg +44 -0
- datalab/data/icons/tour/previous.svg +44 -0
- datalab/data/icons/tour/rewind.svg +51 -0
- datalab/data/icons/tour/stop.svg +47 -0
- datalab/data/icons/tour/tour.svg +16 -0
- datalab/data/icons/uncheck_all.svg +78 -0
- datalab/data/icons/view/curve_antialiasing.svg +50 -0
- datalab/data/icons/view/new_window.svg +98 -0
- datalab/data/icons/view/refresh-auto.svg +57 -0
- datalab/data/icons/view/refresh-manual.svg +51 -0
- datalab/data/icons/view/reset_curve_styles.svg +96 -0
- datalab/data/icons/view/show_first.svg +55 -0
- datalab/data/icons/view/show_titles.svg +46 -0
- datalab/data/icons/visualization.svg +51 -0
- datalab/data/logo/DataLab-Banner-150.png +0 -0
- datalab/data/logo/DataLab-Banner-200.png +0 -0
- datalab/data/logo/DataLab-Banner2-100.png +0 -0
- datalab/data/logo/DataLab-Splash.png +0 -0
- datalab/data/logo/DataLab-watermark.png +0 -0
- datalab/data/logo/DataLab.svg +83 -0
- datalab/data/tests/reordering_test.h5 +0 -0
- datalab/data/tutorials/fabry_perot/fabry-perot1.jpg +0 -0
- datalab/data/tutorials/fabry_perot/fabry-perot2.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_13.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_18.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_23.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_30.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_35.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_40.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_45.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_50.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_55.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_60.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_65.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_70.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_75.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_80.jpg +0 -0
- datalab/env.py +542 -0
- datalab/gui/__init__.py +89 -0
- datalab/gui/actionhandler.py +1701 -0
- datalab/gui/docks.py +473 -0
- datalab/gui/h5io.py +150 -0
- datalab/gui/macroeditor.py +310 -0
- datalab/gui/main.py +2081 -0
- datalab/gui/newobject.py +217 -0
- datalab/gui/objectview.py +766 -0
- datalab/gui/panel/__init__.py +48 -0
- datalab/gui/panel/base.py +3254 -0
- datalab/gui/panel/image.py +157 -0
- datalab/gui/panel/macro.py +607 -0
- datalab/gui/panel/signal.py +164 -0
- datalab/gui/plothandler.py +800 -0
- datalab/gui/processor/__init__.py +84 -0
- datalab/gui/processor/base.py +2456 -0
- datalab/gui/processor/catcher.py +75 -0
- datalab/gui/processor/image.py +1214 -0
- datalab/gui/processor/signal.py +755 -0
- datalab/gui/profiledialog.py +333 -0
- datalab/gui/roieditor.py +633 -0
- datalab/gui/roigrideditor.py +208 -0
- datalab/gui/settings.py +612 -0
- datalab/gui/tour.py +908 -0
- datalab/h5/__init__.py +12 -0
- datalab/h5/common.py +314 -0
- datalab/h5/generic.py +580 -0
- datalab/h5/native.py +39 -0
- datalab/h5/utils.py +95 -0
- datalab/objectmodel.py +640 -0
- datalab/plugins/_readme_.txt +9 -0
- datalab/plugins/datalab_imageformats.py +175 -0
- datalab/plugins/datalab_testdata.py +190 -0
- datalab/plugins.py +355 -0
- datalab/tests/__init__.py +199 -0
- datalab/tests/backbone/__init__.py +1 -0
- datalab/tests/backbone/config_unit_test.py +170 -0
- datalab/tests/backbone/config_versioning_unit_test.py +34 -0
- datalab/tests/backbone/dictlistserial_app_test.py +38 -0
- datalab/tests/backbone/errorcatcher_unit_test.py +69 -0
- datalab/tests/backbone/errormsgbox_unit_test.py +50 -0
- datalab/tests/backbone/execenv_unit.py +262 -0
- datalab/tests/backbone/loadtest_gdi.py +147 -0
- datalab/tests/backbone/long_callback.py +96 -0
- datalab/tests/backbone/main_app_test.py +137 -0
- datalab/tests/backbone/memory_leak.py +43 -0
- datalab/tests/backbone/procisolation1_unit.py +128 -0
- datalab/tests/backbone/procisolation2_unit.py +171 -0
- datalab/tests/backbone/procisolation_unit_test.py +22 -0
- datalab/tests/backbone/profiling_app.py +27 -0
- datalab/tests/backbone/strings_unit_test.py +65 -0
- datalab/tests/backbone/title_formatting_unit_test.py +82 -0
- datalab/tests/conftest.py +131 -0
- datalab/tests/features/__init__.py +1 -0
- datalab/tests/features/applauncher/__init__.py +1 -0
- datalab/tests/features/applauncher/launcher1_app_test.py +28 -0
- datalab/tests/features/applauncher/launcher2_app_test.py +30 -0
- datalab/tests/features/common/__init__.py +1 -0
- datalab/tests/features/common/add_metadata_app_test.py +134 -0
- datalab/tests/features/common/add_metadata_unit_test.py +267 -0
- datalab/tests/features/common/annotations_management_unit_test.py +152 -0
- datalab/tests/features/common/auto_analysis_recompute_unit_test.py +240 -0
- datalab/tests/features/common/createobject_unit_test.py +50 -0
- datalab/tests/features/common/geometry_results_app_test.py +135 -0
- datalab/tests/features/common/interactive_processing_test.py +1109 -0
- datalab/tests/features/common/io_app_test.py +75 -0
- datalab/tests/features/common/large_results_app_test.py +187 -0
- datalab/tests/features/common/metadata_all_patterns_test.py +103 -0
- datalab/tests/features/common/metadata_app_test.py +139 -0
- datalab/tests/features/common/metadata_io_unit_test.py +60 -0
- datalab/tests/features/common/misc_app_test.py +236 -0
- datalab/tests/features/common/multiple_geometry_results_unit_test.py +122 -0
- datalab/tests/features/common/multiple_table_results_unit_test.py +64 -0
- datalab/tests/features/common/operation_modes_app_test.py +392 -0
- datalab/tests/features/common/plot_results_app_test.py +278 -0
- datalab/tests/features/common/reorder_app_test.py +75 -0
- datalab/tests/features/common/result_deletion_unit_test.py +96 -0
- datalab/tests/features/common/result_merged_label_unit_test.py +154 -0
- datalab/tests/features/common/result_shape_settings_unit_test.py +223 -0
- datalab/tests/features/common/roi_plotitem_unit_test.py +64 -0
- datalab/tests/features/common/roieditor_unit_test.py +102 -0
- datalab/tests/features/common/save_to_dir_app_test.py +163 -0
- datalab/tests/features/common/save_to_dir_unit_test.py +474 -0
- datalab/tests/features/common/stat_app_test.py +40 -0
- datalab/tests/features/common/stats_tools_unit_test.py +77 -0
- datalab/tests/features/common/table_results_app_test.py +52 -0
- datalab/tests/features/common/textimport_unit_test.py +131 -0
- datalab/tests/features/common/uuid_preservation_test.py +281 -0
- datalab/tests/features/common/worker_unit_test.py +402 -0
- datalab/tests/features/control/__init__.py +1 -0
- datalab/tests/features/control/connect_dialog.py +28 -0
- datalab/tests/features/control/embedded1_unit_test.py +304 -0
- datalab/tests/features/control/embedded2_unit_test.py +52 -0
- datalab/tests/features/control/remoteclient_app_test.py +219 -0
- datalab/tests/features/control/remoteclient_unit.py +75 -0
- datalab/tests/features/control/simpleclient_unit_test.py +321 -0
- datalab/tests/features/hdf5/__init__.py +1 -0
- datalab/tests/features/hdf5/h5browser1_unit_test.py +31 -0
- datalab/tests/features/hdf5/h5browser2_unit.py +55 -0
- datalab/tests/features/hdf5/h5browser_app_test.py +77 -0
- datalab/tests/features/hdf5/h5import_app_test.py +25 -0
- datalab/tests/features/hdf5/h5importer_app_test.py +34 -0
- datalab/tests/features/image/__init__.py +1 -0
- datalab/tests/features/image/annotations_app_test.py +28 -0
- datalab/tests/features/image/annotations_unit_test.py +80 -0
- datalab/tests/features/image/average_app_test.py +46 -0
- datalab/tests/features/image/background_dialog_test.py +70 -0
- datalab/tests/features/image/blobs_app_test.py +50 -0
- datalab/tests/features/image/contour_app_test.py +42 -0
- datalab/tests/features/image/contour_fabryperot_app_test.py +51 -0
- datalab/tests/features/image/denoise_app_test.py +31 -0
- datalab/tests/features/image/distribute_on_grid_app_test.py +95 -0
- datalab/tests/features/image/edges_app_test.py +31 -0
- datalab/tests/features/image/erase_app_test.py +21 -0
- datalab/tests/features/image/fft2d_app_test.py +27 -0
- datalab/tests/features/image/flatfield_app_test.py +40 -0
- datalab/tests/features/image/geometry_transform_unit_test.py +396 -0
- datalab/tests/features/image/imagetools_app_test.py +51 -0
- datalab/tests/features/image/imagetools_unit_test.py +27 -0
- datalab/tests/features/image/load_app_test.py +73 -0
- datalab/tests/features/image/morph_app_test.py +32 -0
- datalab/tests/features/image/offsetcorrection_app_test.py +30 -0
- datalab/tests/features/image/peak2d_app_test.py +53 -0
- datalab/tests/features/image/profile_app_test.py +73 -0
- datalab/tests/features/image/profile_dialog_test.py +56 -0
- datalab/tests/features/image/roi_app_test.py +98 -0
- datalab/tests/features/image/roi_circ_app_test.py +62 -0
- datalab/tests/features/image/roi_manipulation_app_test.py +268 -0
- datalab/tests/features/image/roigrid_unit_test.py +60 -0
- datalab/tests/features/image/side_by_side_app_test.py +52 -0
- datalab/tests/features/macro/__init__.py +1 -0
- datalab/tests/features/macro/macro_app_test.py +28 -0
- datalab/tests/features/macro/macroeditor_unit_test.py +102 -0
- datalab/tests/features/signal/__init__.py +1 -0
- datalab/tests/features/signal/baseline_dialog_test.py +53 -0
- datalab/tests/features/signal/deltax_dialog_unit_test.py +34 -0
- datalab/tests/features/signal/fft1d_app_test.py +26 -0
- datalab/tests/features/signal/filter_app_test.py +44 -0
- datalab/tests/features/signal/fitdialog_unit_test.py +50 -0
- datalab/tests/features/signal/interpolation_app_test.py +110 -0
- datalab/tests/features/signal/loadbigsignal_app_test.py +80 -0
- datalab/tests/features/signal/multiple_rois_unit_test.py +132 -0
- datalab/tests/features/signal/pulse_features_app_test.py +118 -0
- datalab/tests/features/signal/pulse_features_roi_app_test.py +55 -0
- datalab/tests/features/signal/roi_app_test.py +78 -0
- datalab/tests/features/signal/roi_manipulation_app_test.py +261 -0
- datalab/tests/features/signal/select_xy_cursor_unit_test.py +46 -0
- datalab/tests/features/signal/signalpeakdetection_dialog_test.py +33 -0
- datalab/tests/features/signal/signals_to_image_app_test.py +98 -0
- datalab/tests/features/signal/xarray_compat_app_test.py +128 -0
- datalab/tests/features/tour_unit_test.py +22 -0
- datalab/tests/features/utilities/__init__.py +1 -0
- datalab/tests/features/utilities/installconf_unit_test.py +21 -0
- datalab/tests/features/utilities/logview_app_test.py +21 -0
- datalab/tests/features/utilities/logview_error.py +24 -0
- datalab/tests/features/utilities/logview_unit_test.py +21 -0
- datalab/tests/features/utilities/memstatus_app_test.py +42 -0
- datalab/tests/features/utilities/settings_unit_test.py +88 -0
- datalab/tests/scenarios/__init__.py +1 -0
- datalab/tests/scenarios/beautiful_app.py +121 -0
- datalab/tests/scenarios/common.py +463 -0
- datalab/tests/scenarios/demo.py +212 -0
- datalab/tests/scenarios/example_app_test.py +47 -0
- datalab/tests/scenarios/scenario_h5_app_test.py +75 -0
- datalab/tests/scenarios/scenario_ima1_app_test.py +34 -0
- datalab/tests/scenarios/scenario_ima2_app_test.py +34 -0
- datalab/tests/scenarios/scenario_mac_app_test.py +58 -0
- datalab/tests/scenarios/scenario_sig1_app_test.py +36 -0
- datalab/tests/scenarios/scenario_sig2_app_test.py +35 -0
- datalab/utils/__init__.py +1 -0
- datalab/utils/conf.py +304 -0
- datalab/utils/dephash.py +105 -0
- datalab/utils/qthelpers.py +633 -0
- datalab/utils/strings.py +34 -0
- datalab/utils/tests.py +0 -0
- datalab/widgets/__init__.py +1 -0
- datalab/widgets/connection.py +138 -0
- datalab/widgets/filedialog.py +91 -0
- datalab/widgets/fileviewer.py +84 -0
- datalab/widgets/fitdialog.py +788 -0
- datalab/widgets/h5browser.py +1048 -0
- datalab/widgets/imagebackground.py +111 -0
- datalab/widgets/instconfviewer.py +175 -0
- datalab/widgets/logviewer.py +80 -0
- datalab/widgets/signalbaseline.py +90 -0
- datalab/widgets/signalcursor.py +208 -0
- datalab/widgets/signaldeltax.py +151 -0
- datalab/widgets/signalpeak.py +199 -0
- datalab/widgets/status.py +249 -0
- datalab/widgets/textimport.py +786 -0
- datalab/widgets/warningerror.py +223 -0
- datalab/widgets/wizard.py +286 -0
- datalab_platform-1.0.0.dist-info/METADATA +121 -0
- datalab_platform-1.0.0.dist-info/RECORD +494 -0
- datalab_platform-0.0.1.dev0.dist-info/METADATA +0 -67
- datalab_platform-0.0.1.dev0.dist-info/RECORD +0 -7
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/WHEEL +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/entry_points.txt +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Groups/signals/images reorder test:
|
|
5
|
+
|
|
6
|
+
- Testing groups/signals reorder (images are not tested but the code is the same)
|
|
7
|
+
- When executed in unattended mode, the test only covers the "move up" and
|
|
8
|
+
"move down" actions
|
|
9
|
+
- When executed in interactive mode, the user has to test the "drag and
|
|
10
|
+
drop" actions manually
|
|
11
|
+
- In unattended mode only, we take the opportunity to test other methods of
|
|
12
|
+
the `ObjectModel` class (e.g. `get_group`, `remove_group`, ...) for maximizing
|
|
13
|
+
the code coverage
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# guitest: show
|
|
17
|
+
|
|
18
|
+
from datalab import app
|
|
19
|
+
from datalab.env import execenv
|
|
20
|
+
from datalab.objectmodel import get_uuid
|
|
21
|
+
from datalab.tests import helpers
|
|
22
|
+
from datalab.utils.qthelpers import datalab_app_context
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_reorder():
|
|
26
|
+
"""Run signals/images reorder test scenario"""
|
|
27
|
+
with datalab_app_context(exec_loop=True):
|
|
28
|
+
win = app.create(h5files=[helpers.get_test_fnames("reorder*")[0]])
|
|
29
|
+
panel = win.signalpanel
|
|
30
|
+
view, model = panel.objview, panel.objmodel
|
|
31
|
+
|
|
32
|
+
# Select multiple signals
|
|
33
|
+
objs = [model.get_object_from_number(idx) for idx in (2, 4, 5, 9)]
|
|
34
|
+
view.select_objects(objs)
|
|
35
|
+
# Move up
|
|
36
|
+
view.move_up()
|
|
37
|
+
# Check that the order is correct (note: objects 4 and 5 are not affected
|
|
38
|
+
# by the move up action because they are moved up from the top of their group
|
|
39
|
+
# to the bottom of the previous group)
|
|
40
|
+
assert [model.get_number(obj) for obj in objs] == [1, 4, 5, 8]
|
|
41
|
+
# Move down
|
|
42
|
+
view.move_down()
|
|
43
|
+
# Check that the order is correct (note: objects 4 and 5 are not affected
|
|
44
|
+
# by the move down action because they are moved down from the bottom of their
|
|
45
|
+
# group to the top of the next group)
|
|
46
|
+
assert [model.get_number(obj) for obj in objs] == [2, 4, 5, 9]
|
|
47
|
+
|
|
48
|
+
# Select multiple groups
|
|
49
|
+
groups = [model.get_group_from_number(idx) for idx in (2, 3)]
|
|
50
|
+
view.select_groups(groups)
|
|
51
|
+
# Move up
|
|
52
|
+
view.move_up()
|
|
53
|
+
assert [model.get_number(group) for group in groups] == [1, 2]
|
|
54
|
+
# Move down
|
|
55
|
+
view.move_down()
|
|
56
|
+
assert [model.get_number(group) for group in groups] == [2, 3]
|
|
57
|
+
|
|
58
|
+
# Testing other methods of the `ObjectModel` class in unattended mode only
|
|
59
|
+
if execenv.unattended:
|
|
60
|
+
# Get group
|
|
61
|
+
group = model.get_group_from_number(2)
|
|
62
|
+
assert model.get_number(group) == 2
|
|
63
|
+
# Get the same group from its uuid
|
|
64
|
+
group = model.get_group(get_uuid(group))
|
|
65
|
+
assert model.get_number(group) == 2
|
|
66
|
+
group = model.get_object_or_group(get_uuid(group))
|
|
67
|
+
assert model.get_number(group) == 2
|
|
68
|
+
# Remove group
|
|
69
|
+
n_groups = len(model.get_groups())
|
|
70
|
+
model.remove_group(group)
|
|
71
|
+
assert len(model.get_groups()) == n_groups - 1
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if __name__ == "__main__":
|
|
75
|
+
test_reorder()
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Result deletion unit test
|
|
5
|
+
--------------------------
|
|
6
|
+
|
|
7
|
+
Test the deletion of analysis results from objects.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
11
|
+
# guitest: show
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from sigima.objects import Gauss2DParam, create_image_from_param
|
|
16
|
+
from sigima.tests.data import create_paracetamol_signal
|
|
17
|
+
|
|
18
|
+
from datalab.adapters_metadata import GeometryAdapter, TableAdapter
|
|
19
|
+
from datalab.config import Conf
|
|
20
|
+
from datalab.env import execenv
|
|
21
|
+
from datalab.objectmodel import get_uuid
|
|
22
|
+
from datalab.tests import datalab_test_app_context
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_delete_results_image():
|
|
26
|
+
"""Test deletion of analysis results from images"""
|
|
27
|
+
with datalab_test_app_context(console=False) as win:
|
|
28
|
+
execenv.print("Image result deletion test:")
|
|
29
|
+
panel = win.imagepanel
|
|
30
|
+
|
|
31
|
+
# Create a test image
|
|
32
|
+
param = Gauss2DParam.create(height=200, width=200, sigma=20)
|
|
33
|
+
img = create_image_from_param(param)
|
|
34
|
+
panel.add_object(img)
|
|
35
|
+
|
|
36
|
+
# Run centroid analysis to create results
|
|
37
|
+
execenv.print(" Running centroid analysis...")
|
|
38
|
+
with Conf.proc.show_result_dialog.temp(False):
|
|
39
|
+
panel.processor.run_feature("centroid")
|
|
40
|
+
|
|
41
|
+
# Verify that results exist
|
|
42
|
+
img_refreshed = panel.objmodel[get_uuid(img)]
|
|
43
|
+
adapter_before = GeometryAdapter.from_obj(img_refreshed, "centroid")
|
|
44
|
+
assert adapter_before is not None, (
|
|
45
|
+
"Centroid result should exist before deletion"
|
|
46
|
+
)
|
|
47
|
+
execenv.print(" ✓ Centroid result created")
|
|
48
|
+
|
|
49
|
+
# Delete all results
|
|
50
|
+
execenv.print(" Deleting all results...")
|
|
51
|
+
panel.objview.select_objects([get_uuid(img)])
|
|
52
|
+
panel.delete_results()
|
|
53
|
+
|
|
54
|
+
# Verify that results were deleted
|
|
55
|
+
img_after = panel.objmodel[get_uuid(img)]
|
|
56
|
+
adapter_after = GeometryAdapter.from_obj(img_after, "centroid")
|
|
57
|
+
assert adapter_after is None, "Centroid result should be deleted"
|
|
58
|
+
execenv.print(" ✓ Centroid result deleted")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_delete_results_signal():
|
|
62
|
+
"""Test deletion of analysis results from signals"""
|
|
63
|
+
with datalab_test_app_context(console=False) as win:
|
|
64
|
+
execenv.print("Signal result deletion test:")
|
|
65
|
+
panel = win.signalpanel
|
|
66
|
+
|
|
67
|
+
# Create a test signal
|
|
68
|
+
sig = create_paracetamol_signal()
|
|
69
|
+
panel.add_object(sig)
|
|
70
|
+
|
|
71
|
+
# Run stats analysis to create table results
|
|
72
|
+
execenv.print(" Running stats analysis...")
|
|
73
|
+
with Conf.proc.show_result_dialog.temp(False):
|
|
74
|
+
panel.processor.run_feature("stats")
|
|
75
|
+
|
|
76
|
+
# Verify that results exist
|
|
77
|
+
sig_refreshed = panel.objmodel[get_uuid(sig)]
|
|
78
|
+
tables_before = list(TableAdapter.iterate_from_obj(sig_refreshed))
|
|
79
|
+
assert len(tables_before) > 0, "Stats result should exist before deletion"
|
|
80
|
+
execenv.print(" ✓ Stats result created")
|
|
81
|
+
|
|
82
|
+
# Delete all results
|
|
83
|
+
execenv.print(" Deleting all results...")
|
|
84
|
+
panel.objview.select_objects([get_uuid(sig)])
|
|
85
|
+
panel.delete_results()
|
|
86
|
+
|
|
87
|
+
# Verify that results were deleted
|
|
88
|
+
sig_after = panel.objmodel[get_uuid(sig)]
|
|
89
|
+
tables_after = list(TableAdapter.iterate_from_obj(sig_after))
|
|
90
|
+
assert len(tables_after) == 0, "Stats result should be deleted"
|
|
91
|
+
execenv.print(" ✓ Stats result deleted")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
test_delete_results_image()
|
|
96
|
+
test_delete_results_signal()
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Merged result label test:
|
|
5
|
+
|
|
6
|
+
Test that multiple results are merged into a single label that displays all results.
|
|
7
|
+
|
|
8
|
+
This test verifies that:
|
|
9
|
+
1. Computing FWHM adds a result to the merged label
|
|
10
|
+
2. Computing FW1e2 adds another result to the same merged label
|
|
11
|
+
3. The merged label contains both results
|
|
12
|
+
4. The merged label is read-only (cannot be deleted to remove individual results)
|
|
13
|
+
5. De-selecting and re-selecting the signal maintains the merged label
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
17
|
+
# guitest: show
|
|
18
|
+
|
|
19
|
+
import sigima.params
|
|
20
|
+
import sigima.proc.signal as sips
|
|
21
|
+
from sigima.tests.data import create_paracetamol_signal
|
|
22
|
+
|
|
23
|
+
from datalab.adapters_metadata.geometry_adapter import GeometryAdapter
|
|
24
|
+
from datalab.env import execenv
|
|
25
|
+
from datalab.tests import datalab_test_app_context
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_merged_result_label() -> None:
|
|
29
|
+
"""Test that multiple results are merged into a single label"""
|
|
30
|
+
with datalab_test_app_context() as win:
|
|
31
|
+
panel = win.signalpanel
|
|
32
|
+
|
|
33
|
+
# Create a Gaussian curve
|
|
34
|
+
execenv.print("Creating paracetamol signal...")
|
|
35
|
+
sig = create_paracetamol_signal()
|
|
36
|
+
panel.add_object(sig)
|
|
37
|
+
execenv.print(f" Added signal: {sig.title}")
|
|
38
|
+
|
|
39
|
+
# Compute the FWHM (this adds a result to metadata)
|
|
40
|
+
execenv.print("Computing FWHM...")
|
|
41
|
+
panel.processor.run_feature(sips.fwhm, sigima.params.FWHMParam())
|
|
42
|
+
|
|
43
|
+
# Force refresh to ensure shapes are added
|
|
44
|
+
panel.plothandler.refresh_plot("selected", force=True)
|
|
45
|
+
|
|
46
|
+
# Check that the result metadata exists
|
|
47
|
+
sig = panel.objview.get_sel_objects()[0]
|
|
48
|
+
geometry_results_1 = list(GeometryAdapter.iterate_from_obj(sig))
|
|
49
|
+
execenv.print(f" Geometry results after FWHM: {len(geometry_results_1)}")
|
|
50
|
+
assert len(geometry_results_1) == 1, "Should have one geometry result"
|
|
51
|
+
|
|
52
|
+
# Get the plot and find the merged result label item
|
|
53
|
+
plot = panel.plothandler.plot
|
|
54
|
+
label_items = [item for item in plot.items if hasattr(item, "labelparam")]
|
|
55
|
+
|
|
56
|
+
# Find the merged result label - it should be on the plot
|
|
57
|
+
merged_label = None
|
|
58
|
+
for item in label_items:
|
|
59
|
+
if hasattr(item, "is_readonly") and item.is_readonly():
|
|
60
|
+
merged_label = item
|
|
61
|
+
break
|
|
62
|
+
|
|
63
|
+
assert merged_label is not None, "Should find the merged result label"
|
|
64
|
+
execenv.print(f" Found merged result label: {merged_label.title()}")
|
|
65
|
+
|
|
66
|
+
# Check that the label is read-only
|
|
67
|
+
assert merged_label.is_readonly(), "Merged label should be read-only"
|
|
68
|
+
execenv.print(" ✓ Merged label is read-only")
|
|
69
|
+
|
|
70
|
+
# Get the label text to verify it contains FWHM result
|
|
71
|
+
label_text_1 = merged_label.text_string
|
|
72
|
+
assert "fwhm" in label_text_1.lower(), "Label should contain FWHM result"
|
|
73
|
+
execenv.print(" ✓ Label contains FWHM result")
|
|
74
|
+
|
|
75
|
+
# Compute FW1e2 (this adds another result to metadata)
|
|
76
|
+
execenv.print("Computing FW1e2...")
|
|
77
|
+
panel.processor.run_feature(sips.fw1e2)
|
|
78
|
+
|
|
79
|
+
# Check that we now have two results
|
|
80
|
+
sig = panel.objview.get_sel_objects()[0]
|
|
81
|
+
geometry_results_2 = list(GeometryAdapter.iterate_from_obj(sig))
|
|
82
|
+
execenv.print(f" Geometry results after FW1e2: {len(geometry_results_2)}")
|
|
83
|
+
assert len(geometry_results_2) == 2, "Should have two geometry results"
|
|
84
|
+
|
|
85
|
+
# Verify the merged label now contains both results
|
|
86
|
+
merged_labels = [
|
|
87
|
+
item
|
|
88
|
+
for item in plot.items
|
|
89
|
+
if hasattr(item, "labelparam")
|
|
90
|
+
and hasattr(item, "is_readonly")
|
|
91
|
+
and item.is_readonly()
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
execenv.print(f" Merged result labels on plot: {len(merged_labels)}")
|
|
95
|
+
assert len(merged_labels) == 1, "Should have exactly one merged result label"
|
|
96
|
+
|
|
97
|
+
merged_label_2 = merged_labels[0]
|
|
98
|
+
label_text_2 = merged_label_2.text_string
|
|
99
|
+
assert "fwhm" in label_text_2.lower(), "Label should contain FWHM result"
|
|
100
|
+
assert "fw1e2" in label_text_2.lower(), "Label should contain FW1e2 result"
|
|
101
|
+
assert "<hr>" in label_text_2, "Should contain separator between results"
|
|
102
|
+
execenv.print(" ✓ Merged label contains both FWHM and FW1e2 results")
|
|
103
|
+
|
|
104
|
+
# Create another signal and select it (to deselect the first one)
|
|
105
|
+
execenv.print("Creating second signal to deselect first...")
|
|
106
|
+
sig2 = create_paracetamol_signal()
|
|
107
|
+
sig2.title = "Paracetamol 2"
|
|
108
|
+
panel.add_object(sig2)
|
|
109
|
+
|
|
110
|
+
# Re-select the first signal
|
|
111
|
+
execenv.print("Re-selecting first signal...")
|
|
112
|
+
panel.objview.select_objects([1])
|
|
113
|
+
|
|
114
|
+
# Check that the merged label still exists and contains both results
|
|
115
|
+
sig = panel.objview.get_sel_objects()[0]
|
|
116
|
+
geometry_results_after = list(GeometryAdapter.iterate_from_obj(sig))
|
|
117
|
+
execenv.print(
|
|
118
|
+
f" Geometry results after reselect: {len(geometry_results_after)}"
|
|
119
|
+
)
|
|
120
|
+
assert len(geometry_results_after) == 2, (
|
|
121
|
+
"Should still have two geometry results after re-selection"
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Check that the merged label is still present
|
|
125
|
+
merged_labels_after = [
|
|
126
|
+
item
|
|
127
|
+
for item in plot.items
|
|
128
|
+
if hasattr(item, "labelparam")
|
|
129
|
+
and hasattr(item, "is_readonly")
|
|
130
|
+
and item.is_readonly()
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
execenv.print(
|
|
134
|
+
f" Merged result labels on plot after reselect: {len(merged_labels_after)}"
|
|
135
|
+
)
|
|
136
|
+
assert len(merged_labels_after) == 1, (
|
|
137
|
+
"Should still have one merged result label after re-selection"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
merged_label_final = merged_labels_after[0]
|
|
141
|
+
label_text_final = merged_label_final.text_string
|
|
142
|
+
assert "fwhm" in label_text_final.lower(), (
|
|
143
|
+
"Label should still contain FWHM result"
|
|
144
|
+
)
|
|
145
|
+
assert "fw1e2" in label_text_final.lower(), (
|
|
146
|
+
"Label should still contain FW1e2 result"
|
|
147
|
+
)
|
|
148
|
+
execenv.print(" ✓ Merged label persists after re-selection")
|
|
149
|
+
|
|
150
|
+
execenv.print("✓ Test passed: Merged result label works correctly")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if __name__ == "__main__":
|
|
154
|
+
test_merged_result_label()
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Unit test for visualization settings for annotated shapes and markers.
|
|
5
|
+
|
|
6
|
+
This test verifies that visualization settings (configured in Settings dialog)
|
|
7
|
+
are properly applied when creating geometry results:
|
|
8
|
+
1. Centroid produces a marker (MARKER kind from sigima)
|
|
9
|
+
2. Contour detection produces annotated shapes (CIRCLE, ELLIPSE, or POLYGON kind)
|
|
10
|
+
|
|
11
|
+
The test uses the Conf.view.def*.temp() context manager to temporarily modify
|
|
12
|
+
settings and verify they're applied to new results.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from plotpy.items import AnnotatedCircle, Marker
|
|
18
|
+
from plotpy.styles import MarkerParam, ShapeParam
|
|
19
|
+
from sigima.objects import Gauss2DParam, create_image_from_param
|
|
20
|
+
|
|
21
|
+
from datalab.adapters_metadata import GeometryAdapter
|
|
22
|
+
from datalab.adapters_plotpy import GeometryPlotPyAdapter
|
|
23
|
+
from datalab.config import Conf
|
|
24
|
+
from datalab.env import execenv
|
|
25
|
+
from datalab.tests import datalab_test_app_context
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_ima_shape_param():
|
|
29
|
+
"""Test that annotated shape settings are applied to
|
|
30
|
+
enclosing_circle results on images."""
|
|
31
|
+
with datalab_test_app_context(console=False) as win:
|
|
32
|
+
panel = win.imagepanel
|
|
33
|
+
|
|
34
|
+
# Create a Gaussian image for testing (simple peak for enclosing circle)
|
|
35
|
+
size = 200
|
|
36
|
+
param = Gauss2DParam.create(height=size, width=size, sigma=20)
|
|
37
|
+
img = create_image_from_param(param)
|
|
38
|
+
img.title = "Test Gaussian"
|
|
39
|
+
panel.add_object(img)
|
|
40
|
+
|
|
41
|
+
# Test: Verify annotated shape settings for enclosing circle
|
|
42
|
+
# ----------------------------------------------------------
|
|
43
|
+
execenv.print("\n=== Test: Enclosing Circle (Annotated Shapes) ===")
|
|
44
|
+
|
|
45
|
+
# Create custom annotated shape settings
|
|
46
|
+
def_param = ShapeParam()
|
|
47
|
+
def_param.line.width = 3
|
|
48
|
+
def_param.line.color = "#852727"
|
|
49
|
+
|
|
50
|
+
# Temporarily set the annotated shape settings
|
|
51
|
+
# Note: enclosing_circle is an image feature, so we use ima_shape_param
|
|
52
|
+
with Conf.view.ima_shape_param.temp(def_param):
|
|
53
|
+
# Compute enclosing circle with the custom settings
|
|
54
|
+
with Conf.proc.show_result_dialog.temp(False):
|
|
55
|
+
panel.processor.run_feature("enclosing_circle")
|
|
56
|
+
|
|
57
|
+
# Get the geometry adapter and create plot items
|
|
58
|
+
adapter = GeometryAdapter.from_obj(img, "enclosing_circle")
|
|
59
|
+
assert adapter is not None, "Enclosing circle should be computed"
|
|
60
|
+
|
|
61
|
+
# Create a plotpy adapter to get the shape items
|
|
62
|
+
plotpy_adapter = GeometryPlotPyAdapter(adapter)
|
|
63
|
+
items = list(plotpy_adapter.iterate_shape_items("%.1f", True, "i"))
|
|
64
|
+
|
|
65
|
+
# Verify we got annotated shapes
|
|
66
|
+
assert len(items) > 0, "Should have at least one shape"
|
|
67
|
+
|
|
68
|
+
shape_item = items[0]
|
|
69
|
+
assert isinstance(shape_item, AnnotatedCircle), (
|
|
70
|
+
f"Expected AnnotatedCircle, got {type(shape_item)}"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Verify the annotation settings were applied
|
|
74
|
+
param: ShapeParam = shape_item.shape.shapeparam
|
|
75
|
+
execenv.print(f"Line width: {param.line.width}")
|
|
76
|
+
execenv.print(f"Line color: {param.line.color}")
|
|
77
|
+
assert param.line.width == def_param.line.width, (
|
|
78
|
+
f"Expected line.width={def_param.line.width}, got {param.line.width}"
|
|
79
|
+
)
|
|
80
|
+
assert param.line.color == def_param.line.color, (
|
|
81
|
+
f"Expected line.color={def_param.line.color}, got {param.line.color}"
|
|
82
|
+
)
|
|
83
|
+
execenv.print(
|
|
84
|
+
"✓ Enclosing circle annotated shape settings correctly applied"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
execenv.print("\n=== Test passed ===")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_ima_marker_param():
|
|
91
|
+
"""Test that shape settings are applied to geometry results."""
|
|
92
|
+
with datalab_test_app_context(console=False) as win:
|
|
93
|
+
panel = win.imagepanel
|
|
94
|
+
|
|
95
|
+
# Create a 2D Gaussian image for testing
|
|
96
|
+
size = 200
|
|
97
|
+
param = Gauss2DParam.create(height=size, width=size, sigma=20)
|
|
98
|
+
img = create_image_from_param(param)
|
|
99
|
+
img.title = "Test Gaussian"
|
|
100
|
+
panel.add_object(img)
|
|
101
|
+
|
|
102
|
+
# Test: Verify marker settings for centroid
|
|
103
|
+
# ------------------------------------------
|
|
104
|
+
execenv.print("\n=== Test: Centroid (Marker) ===")
|
|
105
|
+
|
|
106
|
+
# Create custom marker settings
|
|
107
|
+
def_param = MarkerParam()
|
|
108
|
+
def_symbol = def_param.symbol
|
|
109
|
+
def_symbol.marker = "XCross"
|
|
110
|
+
def_symbol.size = 15
|
|
111
|
+
def_symbol.edgecolor = "#316331"
|
|
112
|
+
def_symbol.facecolor = "#291b6b"
|
|
113
|
+
def_symbol.alpha = 0.87
|
|
114
|
+
|
|
115
|
+
# Temporarily set the marker settings
|
|
116
|
+
with Conf.view.ima_marker_param.temp(def_param):
|
|
117
|
+
# Compute centroid with the custom settings
|
|
118
|
+
with Conf.proc.show_result_dialog.temp(False):
|
|
119
|
+
panel.processor.run_feature("centroid")
|
|
120
|
+
|
|
121
|
+
# Get the geometry adapter and create plot items
|
|
122
|
+
adapter = GeometryAdapter.from_obj(img, "centroid")
|
|
123
|
+
assert adapter is not None, "Centroid should be computed"
|
|
124
|
+
|
|
125
|
+
# Create a plotpy adapter to get the marker item
|
|
126
|
+
plotpy_adapter = GeometryPlotPyAdapter(adapter)
|
|
127
|
+
items = list(plotpy_adapter.iterate_shape_items("%.1f", True, "i"))
|
|
128
|
+
|
|
129
|
+
# Verify we got a marker
|
|
130
|
+
assert len(items) > 0, "Should have at least one marker"
|
|
131
|
+
|
|
132
|
+
marker = items[0]
|
|
133
|
+
assert isinstance(marker, Marker), f"Expected Marker, got {type(marker)}"
|
|
134
|
+
|
|
135
|
+
# Verify the marker settings were applied
|
|
136
|
+
symbol = marker.markerparam.symbol
|
|
137
|
+
execenv.print(f"Marker symbol: {symbol.marker}")
|
|
138
|
+
execenv.print(f"Marker size: {symbol.size}")
|
|
139
|
+
execenv.print(f"Marker edge color: {symbol.edgecolor}")
|
|
140
|
+
assert symbol.marker == def_symbol.marker, (
|
|
141
|
+
f"Expected marker='XCross', got '{symbol.marker}'"
|
|
142
|
+
)
|
|
143
|
+
assert symbol.size == def_symbol.size, (
|
|
144
|
+
f"Expected size={def_symbol.size}, got {symbol.size}"
|
|
145
|
+
)
|
|
146
|
+
assert symbol.edgecolor == def_symbol.edgecolor, (
|
|
147
|
+
f"Expected edgecolor={def_symbol.edgecolor}, got {symbol.edgecolor}"
|
|
148
|
+
)
|
|
149
|
+
assert symbol.facecolor == def_symbol.facecolor, (
|
|
150
|
+
f"Expected facecolor={def_symbol.facecolor}, got {symbol.facecolor}"
|
|
151
|
+
)
|
|
152
|
+
execenv.print("✓ Centroid marker settings correctly applied")
|
|
153
|
+
|
|
154
|
+
execenv.print("\n=== Test passed ===")
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def test_refresh_shape_items_after_settings_change():
|
|
158
|
+
"""Test that shape items are refreshed when settings change.
|
|
159
|
+
|
|
160
|
+
This test verifies the fix for the issue where result shapes were not
|
|
161
|
+
updated when refreshing the Image View after changing shape
|
|
162
|
+
parameters in the Settings dialog.
|
|
163
|
+
"""
|
|
164
|
+
with datalab_test_app_context(console=False) as win:
|
|
165
|
+
panel = win.imagepanel
|
|
166
|
+
|
|
167
|
+
# Create a Gaussian image with a result
|
|
168
|
+
size = 200
|
|
169
|
+
param = Gauss2DParam.create(height=size, width=size, sigma=20)
|
|
170
|
+
img = create_image_from_param(param)
|
|
171
|
+
img.title = "Test Gaussian"
|
|
172
|
+
panel.add_object(img)
|
|
173
|
+
|
|
174
|
+
# Compute enclosing circle with initial settings
|
|
175
|
+
with Conf.proc.show_result_dialog.temp(False):
|
|
176
|
+
panel.processor.run_feature("enclosing_circle")
|
|
177
|
+
|
|
178
|
+
# Get initial shape item styling
|
|
179
|
+
plot = panel.plothandler.plot
|
|
180
|
+
shape_items = [item for item in plot.items if isinstance(item, AnnotatedCircle)]
|
|
181
|
+
assert len(shape_items) > 0, "Should have at least one shape item"
|
|
182
|
+
|
|
183
|
+
initial_width = shape_items[0].shape.shapeparam.line.width
|
|
184
|
+
initial_color = shape_items[0].shape.shapeparam.line.color
|
|
185
|
+
|
|
186
|
+
execenv.print(f"Initial shape: width={initial_width}, color={initial_color}")
|
|
187
|
+
|
|
188
|
+
# Change temporarily the shape parameters
|
|
189
|
+
new_param = ShapeParam()
|
|
190
|
+
new_param.line.width = 5
|
|
191
|
+
new_param.line.color = "#00ff00"
|
|
192
|
+
with Conf.view.ima_shape_param.temp(new_param):
|
|
193
|
+
# Call refresh_all_shape_items() to apply new settings
|
|
194
|
+
panel.plothandler.refresh_all_shape_items()
|
|
195
|
+
|
|
196
|
+
# Get updated shape items
|
|
197
|
+
shape_items_after = [
|
|
198
|
+
item for item in plot.items if isinstance(item, AnnotatedCircle)
|
|
199
|
+
]
|
|
200
|
+
assert len(shape_items_after) > 0, (
|
|
201
|
+
"Should still have shape items after refresh"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
updated_width = shape_items_after[0].shape.shapeparam.line.width
|
|
205
|
+
updated_color = shape_items_after[0].shape.shapeparam.line.color
|
|
206
|
+
|
|
207
|
+
execenv.print(
|
|
208
|
+
f"Updated shape: width={updated_width}, color={updated_color}"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
# Verify the shape was updated with new settings
|
|
212
|
+
assert updated_width == 5, f"Expected width 5, got {updated_width}"
|
|
213
|
+
assert updated_color == "#00ff00", (
|
|
214
|
+
f"Expected color #00ff00, got {updated_color}"
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
execenv.print("✓ Shape items correctly refreshed after settings change\n")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
if __name__ == "__main__":
|
|
221
|
+
test_ima_shape_param()
|
|
222
|
+
test_ima_marker_param()
|
|
223
|
+
test_refresh_shape_items_after_settings_change()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
ROI to plot item conversion unit tests
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
8
|
+
# guitest: show
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
import sigima.objects
|
|
14
|
+
from guidata.qthelpers import qt_app_context
|
|
15
|
+
from sigima.tests.data import (
|
|
16
|
+
create_multigaussian_image,
|
|
17
|
+
create_paracetamol_signal,
|
|
18
|
+
create_test_image_rois,
|
|
19
|
+
create_test_signal_rois,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
from datalab.adapters_plotpy import create_adapter_from_object, plotitem_to_singleroi
|
|
23
|
+
from datalab.env import execenv
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def __conversion_methods(
|
|
27
|
+
roi: sigima.objects.SignalROI | sigima.objects.ImageROI,
|
|
28
|
+
obj: sigima.objects.SignalObj | sigima.objects.ImageObj,
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Test conversion methods for single ROI objects"""
|
|
31
|
+
execenv.print(" test `to_plot_item` and `from_plot_item` methods: ", end="")
|
|
32
|
+
single_roi = roi.get_single_roi(0)
|
|
33
|
+
with qt_app_context(exec_loop=False):
|
|
34
|
+
plot_item = create_adapter_from_object(single_roi).to_plot_item(obj)
|
|
35
|
+
sroi_new = plotitem_to_singleroi(plot_item)
|
|
36
|
+
orig_coords = [float(val) for val in single_roi.get_physical_coords(obj)]
|
|
37
|
+
new_coords = [float(val) for val in sroi_new.get_physical_coords(obj)]
|
|
38
|
+
execenv.print(f"{orig_coords} --> {new_coords}")
|
|
39
|
+
assert np.array_equal(orig_coords, new_coords)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_signal_roi_plotitem_conversion() -> None:
|
|
43
|
+
"""Test signal ROIs conversion to/from plot items"""
|
|
44
|
+
execenv.print("==============================================")
|
|
45
|
+
execenv.print("Test signal ROIs conversion to/from plot items")
|
|
46
|
+
execenv.print("==============================================")
|
|
47
|
+
obj = create_paracetamol_signal()
|
|
48
|
+
for roi in create_test_signal_rois(obj):
|
|
49
|
+
__conversion_methods(roi, obj)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_image_roi_plotitem_conversion() -> None:
|
|
53
|
+
"""Test image ROIs conversion to/from plot items"""
|
|
54
|
+
execenv.print("==============================================")
|
|
55
|
+
execenv.print("Test image ROIs conversion to/from plot items")
|
|
56
|
+
execenv.print("==============================================")
|
|
57
|
+
obj = create_multigaussian_image()
|
|
58
|
+
for roi in create_test_image_rois(obj):
|
|
59
|
+
__conversion_methods(roi, obj)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
test_signal_roi_plotitem_conversion()
|
|
64
|
+
test_image_roi_plotitem_conversion()
|