datalab-platform 0.0.1.dev0__py3-none-any.whl → 1.0.1__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.1.dist-info/METADATA +121 -0
- datalab_platform-1.0.1.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.1.dist-info}/WHEEL +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/entry_points.txt +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.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
|
+
I/O application test:
|
|
5
|
+
|
|
6
|
+
- Testing signals I/O
|
|
7
|
+
- Testing images I/O
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# guitest: show
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import os.path as osp
|
|
15
|
+
|
|
16
|
+
from sigima.io.base import IOAction
|
|
17
|
+
from sigima.io.image import ImageIORegistry
|
|
18
|
+
from sigima.io.signal import SignalIORegistry
|
|
19
|
+
|
|
20
|
+
from datalab.env import execenv
|
|
21
|
+
from datalab.gui.panel.base import BaseDataPanel
|
|
22
|
+
from datalab.tests import datalab_test_app_context, helpers
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __testfunc(
|
|
26
|
+
title: str,
|
|
27
|
+
panel: BaseDataPanel,
|
|
28
|
+
registry: SignalIORegistry | ImageIORegistry,
|
|
29
|
+
pattern: str,
|
|
30
|
+
in_folder: str,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""Test I/O features"""
|
|
33
|
+
execenv.print(f" {title}:")
|
|
34
|
+
with helpers.WorkdirRestoringTempDir() as tmpdir:
|
|
35
|
+
# os.startfile(tmpdir)
|
|
36
|
+
fnames = helpers.get_test_fnames(pattern, in_folder)
|
|
37
|
+
execenv.print(" Opening:")
|
|
38
|
+
# TODO: [P3] This test does not support formats that return multiple objects
|
|
39
|
+
# (e.g. SIF files with multiple images). As a consequence, it will not test
|
|
40
|
+
# thoroughly the I/O functionalities for these formats (it will keep only the
|
|
41
|
+
# first object in the list of returned objects)
|
|
42
|
+
objs = []
|
|
43
|
+
for fname in fnames:
|
|
44
|
+
execenv.print(f" {fname}: ", end="")
|
|
45
|
+
try:
|
|
46
|
+
registry.get_format(fname, IOAction.LOAD)
|
|
47
|
+
except NotImplementedError:
|
|
48
|
+
execenv.print("Skipped (not supported)")
|
|
49
|
+
continue
|
|
50
|
+
objs.append(panel.load_from_files([fname])[0])
|
|
51
|
+
execenv.print("OK")
|
|
52
|
+
execenv.print(" Saving:")
|
|
53
|
+
for fname, obj in zip(fnames, objs):
|
|
54
|
+
panel.objview.set_current_object(obj)
|
|
55
|
+
path = osp.join(tmpdir, osp.basename(fname))
|
|
56
|
+
execenv.print(f" {path}: ", end="")
|
|
57
|
+
try:
|
|
58
|
+
registry.get_format(fname, IOAction.SAVE)
|
|
59
|
+
except NotImplementedError:
|
|
60
|
+
execenv.print("Skipped (not supported)")
|
|
61
|
+
continue
|
|
62
|
+
panel.save_to_files([path])
|
|
63
|
+
execenv.print("OK")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_io_app() -> None:
|
|
67
|
+
"""Run image tools test scenario"""
|
|
68
|
+
with datalab_test_app_context() as win:
|
|
69
|
+
execenv.print("I/O application test:")
|
|
70
|
+
__testfunc("Signals", win.signalpanel, SignalIORegistry, "*.*", "curve_formats")
|
|
71
|
+
__testfunc("Images", win.imagepanel, ImageIORegistry, "*.*", "image_formats")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if __name__ == "__main__":
|
|
75
|
+
test_io_app()
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Large Results Application Test Module
|
|
5
|
+
|
|
6
|
+
This module contains tests for verifying that DataLab handles large result datasets
|
|
7
|
+
efficiently and correctly.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
11
|
+
# guitest: show,skip
|
|
12
|
+
|
|
13
|
+
import time
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
import sigima.enums
|
|
17
|
+
import sigima.objects
|
|
18
|
+
import sigima.params as sigima_param
|
|
19
|
+
from sigima.tests.data import get_test_image
|
|
20
|
+
|
|
21
|
+
from datalab.adapters_metadata.geometry_adapter import GeometryAdapter
|
|
22
|
+
from datalab.config import Conf
|
|
23
|
+
from datalab.tests import datalab_test_app_context
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def create_polygon_vertices(
|
|
27
|
+
x0: float, y0: float, nb_points: int, radius_mean: float, radius_variation: float
|
|
28
|
+
) -> list[tuple[float, float]]:
|
|
29
|
+
"""Generate points for a polygon around (x0, y0)
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
x0: x coordinate of the polygon center
|
|
33
|
+
y0: y coordinate of the polygon center
|
|
34
|
+
nb_points: number of points to generate
|
|
35
|
+
radius_mean: mean radius of the polygon
|
|
36
|
+
radius_variation: variation in radius
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
List of (x, y) points representing the polygon vertices
|
|
40
|
+
"""
|
|
41
|
+
points = []
|
|
42
|
+
# Calculate number of NaNs to append (random numbers between 0 and nb_points-10):
|
|
43
|
+
num_nans = np.random.randint(0, nb_points - 10)
|
|
44
|
+
for j in range(nb_points - num_nans):
|
|
45
|
+
angle = j * (2 * np.pi / (nb_points - num_nans))
|
|
46
|
+
radius = radius_mean + radius_variation * np.random.rand()
|
|
47
|
+
x = x0 + radius * np.cos(angle)
|
|
48
|
+
y = y0 + radius * np.sin(angle)
|
|
49
|
+
points.append((x, y))
|
|
50
|
+
for _ in range(num_nans):
|
|
51
|
+
points.append((np.nan, np.nan))
|
|
52
|
+
return points
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def create_random_polygons(
|
|
56
|
+
size: int, nb_polygons: int, nb_points_per_polygon: int
|
|
57
|
+
) -> np.ndarray:
|
|
58
|
+
"""Create random polygons
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
size: size of the area in which to create polygons
|
|
62
|
+
nb_polygons: number of polygons to create
|
|
63
|
+
nb_points_per_polygon: number of points per polygon
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Array of shape (nb_polygons, nb_points_per_polygon, 2)
|
|
67
|
+
"""
|
|
68
|
+
polygons = []
|
|
69
|
+
for _ in range(nb_polygons):
|
|
70
|
+
x0 = size * np.random.rand()
|
|
71
|
+
y0 = size * np.random.rand()
|
|
72
|
+
points = create_polygon_vertices(
|
|
73
|
+
x0, y0, nb_points_per_polygon, radius_mean=20, radius_variation=30
|
|
74
|
+
)
|
|
75
|
+
# Append the flattened points:
|
|
76
|
+
polygons.append(points)
|
|
77
|
+
return np.array(polygons)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_large_results_scenario(measure_execution_time: bool = False) -> None:
|
|
81
|
+
"""Test scenario to verify result truncation limits work correctly
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
measure_execution_time: if True, measure and print the execution time, then
|
|
85
|
+
quit immediately
|
|
86
|
+
|
|
87
|
+
This scenario tests:
|
|
88
|
+
- Contour detection on flower.npy (generates many contours)
|
|
89
|
+
- Shape drawing truncation at max_shapes_to_draw limit
|
|
90
|
+
- Label display truncation at max_cells_in_label limit
|
|
91
|
+
- Performance with large polygons (many points per polygon)
|
|
92
|
+
|
|
93
|
+
Performance benchmark (15 polygons × 5000 points):
|
|
94
|
+
- Pure PlotPy: ~473ms (baseline for drawing shapes only)
|
|
95
|
+
- DataLab: ~254ms (includes shape drawing + HTML label generation)
|
|
96
|
+
- Note: DataLab is faster due to optimized HTML truncation before formatting
|
|
97
|
+
"""
|
|
98
|
+
nb_polygons = 15
|
|
99
|
+
nb_points_per_polygon = 5000
|
|
100
|
+
|
|
101
|
+
with datalab_test_app_context(
|
|
102
|
+
console=False, exec_loop=not measure_execution_time
|
|
103
|
+
) as win:
|
|
104
|
+
# Create an image panel
|
|
105
|
+
panel = win.imagepanel
|
|
106
|
+
|
|
107
|
+
# Load the flower test image
|
|
108
|
+
ima = get_test_image("flower.npy")
|
|
109
|
+
ima.title = "Test image 'flower.npy' - Contour Detection Limit Test"
|
|
110
|
+
panel.add_object(ima)
|
|
111
|
+
|
|
112
|
+
# Apply Roberts filter for edge detection
|
|
113
|
+
panel.processor.run_feature("roberts")
|
|
114
|
+
|
|
115
|
+
# Run contour detection which should produce a large set of results
|
|
116
|
+
param = sigima_param.ContourShapeParam()
|
|
117
|
+
param.shape = sigima.enums.ContourShape.POLYGON
|
|
118
|
+
with Conf.proc.show_result_dialog.temp(False):
|
|
119
|
+
panel.processor.run_feature("contour_shape", param)
|
|
120
|
+
|
|
121
|
+
# Create geometry results manually using many polygons (we generate results
|
|
122
|
+
# in a manner that should be similar to what contour detection would typically
|
|
123
|
+
# produce but in a way that we can control precisely here)
|
|
124
|
+
vertices = create_random_polygons(
|
|
125
|
+
size=ima.data.shape[0],
|
|
126
|
+
nb_polygons=nb_polygons,
|
|
127
|
+
nb_points_per_polygon=nb_points_per_polygon,
|
|
128
|
+
)
|
|
129
|
+
geom_result = sigima.objects.GeometryResult(
|
|
130
|
+
title="Polygon",
|
|
131
|
+
kind=sigima.objects.KindShape.POLYGON,
|
|
132
|
+
coords=vertices.reshape(-1, nb_points_per_polygon * 2),
|
|
133
|
+
func_name="contour_detection_test",
|
|
134
|
+
)
|
|
135
|
+
geom_adapter = GeometryAdapter(geom_result)
|
|
136
|
+
|
|
137
|
+
ima2 = ima.copy()
|
|
138
|
+
geom_adapter.add_to(ima2)
|
|
139
|
+
panel.add_object(ima2)
|
|
140
|
+
|
|
141
|
+
if measure_execution_time:
|
|
142
|
+
# Now measure the execution time of switching selection between
|
|
143
|
+
# the 3 images:
|
|
144
|
+
# Image #1: flower.npy, as loaded
|
|
145
|
+
# Image #2: Image #1 after Roberts filter + contour detection
|
|
146
|
+
# Image #3: Image #1 with manually added large polygon result
|
|
147
|
+
print("\nMeasuring image switch timings...")
|
|
148
|
+
image_switch_times = {}
|
|
149
|
+
for _j in range(2): # Doing multiple iterations to stabilize timings
|
|
150
|
+
panel.objview.select_objects([1])
|
|
151
|
+
for i in range(2, 4):
|
|
152
|
+
start_time = time.perf_counter()
|
|
153
|
+
panel.objview.select_objects([i])
|
|
154
|
+
elapsed_time = (time.perf_counter() - start_time) * 1000 # in ms
|
|
155
|
+
image_switch_times.setdefault(i, []).append(elapsed_time)
|
|
156
|
+
print(f" - Switch to image #{i}: {elapsed_time:.1f} ms")
|
|
157
|
+
print("\nImage switch timings (ms):")
|
|
158
|
+
for i in range(2, 4):
|
|
159
|
+
times = image_switch_times[i]
|
|
160
|
+
avg_time = sum(times) / len(times)
|
|
161
|
+
print(
|
|
162
|
+
f" - Switching to image #{i}: avg {avg_time:.1f} ms "
|
|
163
|
+
f"over {len(times)} runs"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
# Measure execution time of manual refresh of the image view:
|
|
167
|
+
print("\nMeasuring image view refresh timings...")
|
|
168
|
+
image_refresh_times = {}
|
|
169
|
+
for i in range(3, 4):
|
|
170
|
+
panel.objview.select_objects([i])
|
|
171
|
+
for _j in range(5): # Doing multiple iterations to stabilize timings
|
|
172
|
+
start_time = time.perf_counter()
|
|
173
|
+
panel.manual_refresh()
|
|
174
|
+
elapsed_time = (time.perf_counter() - start_time) * 1000 # in ms
|
|
175
|
+
image_refresh_times.setdefault(i, []).append(elapsed_time)
|
|
176
|
+
print(f" - Manual refresh: {elapsed_time:.1f} ms")
|
|
177
|
+
print("\nImage view refresh timings (ms):")
|
|
178
|
+
for i in range(3, 4):
|
|
179
|
+
times = image_refresh_times[i]
|
|
180
|
+
avg_time = sum(times) / len(times)
|
|
181
|
+
print(
|
|
182
|
+
f" - Manual refresh: avg {avg_time:.1f} ms over {len(times)} runs"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
if __name__ == "__main__":
|
|
187
|
+
test_large_results_scenario(measure_execution_time=False)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Processing metadata storage tests
|
|
5
|
+
|
|
6
|
+
Tests that ALL processing patterns (1-to-1, 2-to-1, n-to-1) correctly
|
|
7
|
+
store metadata in object metadata options, regardless of whether they
|
|
8
|
+
support interactive re-processing.
|
|
9
|
+
|
|
10
|
+
This is an integration test that verifies the metadata storage infrastructure
|
|
11
|
+
works correctly across all computation patterns.
|
|
12
|
+
|
|
13
|
+
Note: interactive_processing_test.py tests the interactive re-processing UI feature.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# guitest: show
|
|
17
|
+
|
|
18
|
+
import guidata.dataset as gds
|
|
19
|
+
from guidata.qthelpers import qt_app_context
|
|
20
|
+
from sigima.proc.signal.filtering import GaussianParam
|
|
21
|
+
|
|
22
|
+
from datalab.gui.processor.base import PROCESSING_PARAMETERS_OPTION
|
|
23
|
+
from datalab.objectmodel import get_uuid
|
|
24
|
+
from datalab.tests import datalab_test_app_context
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_metadata_all_patterns():
|
|
28
|
+
"""Test that metadata is stored for all processing patterns."""
|
|
29
|
+
with qt_app_context():
|
|
30
|
+
with datalab_test_app_context() as win:
|
|
31
|
+
# Get panels
|
|
32
|
+
sig_panel = win.signalpanel
|
|
33
|
+
img_panel = win.imagepanel
|
|
34
|
+
|
|
35
|
+
# === Test 1: 1-to-1 pattern (with parameters) ===
|
|
36
|
+
sig_panel.new_object()
|
|
37
|
+
sig1 = sig_panel.objmodel.get_all_objects()[-1]
|
|
38
|
+
|
|
39
|
+
param = GaussianParam.create(sigma=2.0)
|
|
40
|
+
sig_panel.processor.compute_1_to_1(
|
|
41
|
+
sig_panel.processor.get_feature("gaussian_filter").function,
|
|
42
|
+
param=param,
|
|
43
|
+
title="Gaussian filter",
|
|
44
|
+
)
|
|
45
|
+
filtered_sig = sig_panel.objmodel.get_all_objects()[-1]
|
|
46
|
+
|
|
47
|
+
# Check metadata contains all keys including pattern type
|
|
48
|
+
assert PROCESSING_PARAMETERS_OPTION in filtered_sig.get_metadata_options()
|
|
49
|
+
option_dict = filtered_sig.get_metadata_option(PROCESSING_PARAMETERS_OPTION)
|
|
50
|
+
assert option_dict["func_name"] == "gaussian_filter"
|
|
51
|
+
assert option_dict["pattern"] == "1-to-1"
|
|
52
|
+
assert option_dict["source_uuid"] == get_uuid(sig1)
|
|
53
|
+
assert option_dict["param_json"] == gds.dataset_to_json(param)
|
|
54
|
+
|
|
55
|
+
# === Test 2: 2-to-1 pattern (single operand) ===
|
|
56
|
+
sig_panel.new_object()
|
|
57
|
+
sig2 = sig_panel.objmodel.get_all_objects()[-1]
|
|
58
|
+
sig_panel.objview.select_objects([sig1]) # Select only sig1
|
|
59
|
+
sig_panel.processor.compute_2_to_1(
|
|
60
|
+
obj2=sig2,
|
|
61
|
+
obj2_name="signal to subtract",
|
|
62
|
+
func=sig_panel.processor.get_feature("difference").function,
|
|
63
|
+
title="Difference",
|
|
64
|
+
)
|
|
65
|
+
subtracted_sig = sig_panel.objmodel.get_all_objects()[-1]
|
|
66
|
+
|
|
67
|
+
# Check lightweight metadata (no params, but has pattern and sources)
|
|
68
|
+
assert PROCESSING_PARAMETERS_OPTION in subtracted_sig.get_metadata_options()
|
|
69
|
+
option_dict = subtracted_sig.get_metadata_option(
|
|
70
|
+
PROCESSING_PARAMETERS_OPTION
|
|
71
|
+
)
|
|
72
|
+
assert option_dict["pattern"] == "2-to-1"
|
|
73
|
+
assert option_dict["source_uuids"] == [get_uuid(sig1), get_uuid(sig2)]
|
|
74
|
+
assert len(option_dict["source_uuids"]) == 2
|
|
75
|
+
# Should NOT have full parameters stored
|
|
76
|
+
assert "param" not in option_dict
|
|
77
|
+
|
|
78
|
+
# === Test 3: n-to-1 pattern (single operand mode) ===
|
|
79
|
+
img_panel.new_object()
|
|
80
|
+
img1 = img_panel.objmodel.get_all_objects()[-1]
|
|
81
|
+
img_panel.new_object()
|
|
82
|
+
img2 = img_panel.objmodel.get_all_objects()[-1]
|
|
83
|
+
img_panel.objview.select_objects([img1, img2])
|
|
84
|
+
img_panel.processor.compute_n_to_1(
|
|
85
|
+
func=img_panel.processor.get_feature("addition").function,
|
|
86
|
+
title="Addition",
|
|
87
|
+
)
|
|
88
|
+
sum_img = img_panel.objmodel.get_all_objects()[-1]
|
|
89
|
+
|
|
90
|
+
# Check lightweight metadata
|
|
91
|
+
assert PROCESSING_PARAMETERS_OPTION in sum_img.get_metadata_options()
|
|
92
|
+
option_dict = sum_img.get_metadata_option(PROCESSING_PARAMETERS_OPTION)
|
|
93
|
+
assert option_dict["pattern"] == "n-to-1"
|
|
94
|
+
assert "source_uuids" in option_dict
|
|
95
|
+
assert len(option_dict["source_uuids"]) == 2
|
|
96
|
+
# Should NOT have full parameters stored
|
|
97
|
+
assert "param" not in option_dict
|
|
98
|
+
|
|
99
|
+
print("✓ All processing patterns store appropriate metadata")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
test_metadata_all_patterns()
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Metadata application test:
|
|
5
|
+
|
|
6
|
+
- Create signal/image, with ROI
|
|
7
|
+
- Compute things (adds metadata)
|
|
8
|
+
- Test metadata delete, copy, paste
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
12
|
+
# guitest: show
|
|
13
|
+
|
|
14
|
+
import sigima.objects
|
|
15
|
+
import sigima.params
|
|
16
|
+
import sigima.proc.image as sipi
|
|
17
|
+
import sigima.proc.signal as sips
|
|
18
|
+
from sigima.tests.data import create_paracetamol_signal
|
|
19
|
+
|
|
20
|
+
from datalab.adapters_metadata.geometry_adapter import GeometryAdapter
|
|
21
|
+
from datalab.env import execenv
|
|
22
|
+
from datalab.gui.panel.base import BaseDataPanel, PasteMetadataParam
|
|
23
|
+
from datalab.gui.panel.image import ImagePanel
|
|
24
|
+
from datalab.gui.panel.signal import SignalPanel
|
|
25
|
+
from datalab.tests import datalab_test_app_context
|
|
26
|
+
from datalab.tests.features.image.roi_app_test import create_test_image_with_roi
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def __run_signal_computations(panel: SignalPanel):
|
|
30
|
+
"""Test all signal features related to ROI"""
|
|
31
|
+
execenv.print(" Signal features")
|
|
32
|
+
panel.processor.run_feature(sips.fwhm, sigima.params.FWHMParam())
|
|
33
|
+
panel.processor.run_feature(sips.fw1e2)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def __run_image_computations(panel: ImagePanel):
|
|
37
|
+
"""Test all image features related to ROI"""
|
|
38
|
+
execenv.print(" Image features")
|
|
39
|
+
panel.processor.run_feature(sipi.centroid)
|
|
40
|
+
panel.processor.run_feature(sipi.enclosing_circle)
|
|
41
|
+
panel.processor.run_feature(
|
|
42
|
+
sipi.peak_detection, sigima.params.Peak2DDetectionParam()
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def __test_metadata_features(panel: BaseDataPanel):
|
|
47
|
+
"""Test all metadata features"""
|
|
48
|
+
# Duplicate the first object
|
|
49
|
+
panel.duplicate_object()
|
|
50
|
+
|
|
51
|
+
# Delete metadata of the first object
|
|
52
|
+
for keep_roi in (True, False): # Test both cases (coverage test)
|
|
53
|
+
panel.delete_metadata(keep_roi=keep_roi)
|
|
54
|
+
|
|
55
|
+
# Select and copy metadata of the second object
|
|
56
|
+
panel.objview.select_objects([2])
|
|
57
|
+
source_obj = panel.objview.get_sel_objects()[0]
|
|
58
|
+
source_metadata = source_obj.metadata.copy()
|
|
59
|
+
|
|
60
|
+
# Verify source object has geometry results
|
|
61
|
+
geometry_keys = [
|
|
62
|
+
k for k, v in source_metadata.items() if GeometryAdapter.match(k, v)
|
|
63
|
+
]
|
|
64
|
+
execenv.print(f" Source object has {len(geometry_keys)} geometry metadata keys")
|
|
65
|
+
assert len(geometry_keys) > 0, "Source object should have geometry results"
|
|
66
|
+
|
|
67
|
+
# Copy metadata
|
|
68
|
+
panel.copy_metadata()
|
|
69
|
+
|
|
70
|
+
# Select and paste metadata to the first object
|
|
71
|
+
panel.objview.select_objects([1])
|
|
72
|
+
target_obj = panel.objview.get_sel_objects()[0]
|
|
73
|
+
|
|
74
|
+
# Verify target has no geometry metadata before paste
|
|
75
|
+
target_geo_keys_before = [
|
|
76
|
+
k for k, v in target_obj.metadata.items() if GeometryAdapter.match(k, v)
|
|
77
|
+
]
|
|
78
|
+
execenv.print(
|
|
79
|
+
f" Target object has {len(target_geo_keys_before)} geometry keys before paste"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Paste metadata (with default parameters - keep everything)
|
|
83
|
+
param = PasteMetadataParam("Test paste")
|
|
84
|
+
param.keep_geometry = True
|
|
85
|
+
param.keep_tables = True
|
|
86
|
+
param.keep_other = True
|
|
87
|
+
param.keep_roi = True
|
|
88
|
+
panel.paste_metadata(param)
|
|
89
|
+
|
|
90
|
+
# Verify the paste worked
|
|
91
|
+
target_metadata_after = target_obj.metadata.copy()
|
|
92
|
+
target_geo_keys_after = [
|
|
93
|
+
k for k, v in target_metadata_after.items() if GeometryAdapter.match(k, v)
|
|
94
|
+
]
|
|
95
|
+
execenv.print(
|
|
96
|
+
f" Target object has {len(target_geo_keys_after)} geometry keys after paste"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Check that geometry metadata was actually pasted
|
|
100
|
+
assert len(target_geo_keys_after) > 0, (
|
|
101
|
+
"Target object should have geometry results after paste"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Verify that all geometry metadata uses the new unified format (_dict)
|
|
105
|
+
for key in target_geo_keys_after:
|
|
106
|
+
# Verify the geometry data is valid
|
|
107
|
+
geometry_data = target_metadata_after[key]
|
|
108
|
+
assert isinstance(geometry_data, dict), f"Geometry data should be dict: {key}"
|
|
109
|
+
assert "title" in geometry_data, f"Missing title in geometry data: {key}"
|
|
110
|
+
assert "coords" in geometry_data, f"Missing coords in geometry data: {key}"
|
|
111
|
+
execenv.print(f" ✓ Valid geometry entry: {key}")
|
|
112
|
+
|
|
113
|
+
execenv.print(" ✓ Metadata copy/paste verification passed")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_metadata_app():
|
|
117
|
+
"""Run metadata application test scenario"""
|
|
118
|
+
size = 200
|
|
119
|
+
with datalab_test_app_context() as win:
|
|
120
|
+
execenv.print("Metadata application test:")
|
|
121
|
+
# === Signal metadata features test ===
|
|
122
|
+
panel = win.signalpanel
|
|
123
|
+
sig = create_paracetamol_signal(size)
|
|
124
|
+
sig.roi = sigima.objects.create_signal_roi([[26, 41], [125, 146]], indices=True)
|
|
125
|
+
panel.add_object(sig)
|
|
126
|
+
__run_signal_computations(panel)
|
|
127
|
+
__test_metadata_features(panel)
|
|
128
|
+
# === Image metadata features test ===
|
|
129
|
+
panel = win.imagepanel
|
|
130
|
+
param = sigima.objects.NewImageParam.create(height=size, width=size)
|
|
131
|
+
ima = create_test_image_with_roi(param)
|
|
132
|
+
panel.add_object(ima)
|
|
133
|
+
__run_image_computations(panel)
|
|
134
|
+
__test_metadata_features(panel)
|
|
135
|
+
execenv.print("==> OK")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if __name__ == "__main__":
|
|
139
|
+
test_metadata_app()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Metadata import/export unit test:
|
|
5
|
+
|
|
6
|
+
- Create an image with annotations, geometry result and table results
|
|
7
|
+
- Add the image to DataLab
|
|
8
|
+
- Export image metadata to file (JSON)
|
|
9
|
+
- Delete image metadata
|
|
10
|
+
- Import image metadata from previous file
|
|
11
|
+
- Check if image metadata is the same as the original image
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# guitest: show
|
|
15
|
+
|
|
16
|
+
import os.path as osp
|
|
17
|
+
|
|
18
|
+
from sigima.tests import data as test_data
|
|
19
|
+
|
|
20
|
+
from datalab.adapters_metadata import GeometryAdapter, TableAdapter
|
|
21
|
+
from datalab.env import execenv
|
|
22
|
+
from datalab.tests import datalab_test_app_context, helpers
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_metadata_io_unit():
|
|
26
|
+
"""Run image tools test scenario"""
|
|
27
|
+
with execenv.context(unattended=True):
|
|
28
|
+
with helpers.WorkdirRestoringTempDir() as tmpdir:
|
|
29
|
+
fname = osp.join(tmpdir, "test.dlabmeta")
|
|
30
|
+
with datalab_test_app_context() as win:
|
|
31
|
+
panel = win.imagepanel
|
|
32
|
+
|
|
33
|
+
# Create a test image with annotations
|
|
34
|
+
ima = test_data.create_annotated_image()
|
|
35
|
+
|
|
36
|
+
# Add geometry results to test their serialization
|
|
37
|
+
for geometry in test_data.generate_geometry_results():
|
|
38
|
+
GeometryAdapter(geometry).add_to(ima)
|
|
39
|
+
|
|
40
|
+
# Add table results to test their serialization
|
|
41
|
+
for table in test_data.generate_table_results():
|
|
42
|
+
TableAdapter(table).add_to(ima)
|
|
43
|
+
|
|
44
|
+
panel.add_object(ima)
|
|
45
|
+
orig_metadata = ima.metadata.copy()
|
|
46
|
+
panel.export_metadata_from_file(fname)
|
|
47
|
+
panel.delete_metadata()
|
|
48
|
+
|
|
49
|
+
# The +1 is for the "number" metadata option which has no default:
|
|
50
|
+
assert len(ima.metadata) == len(ima.get_metadata_options_defaults()) + 1
|
|
51
|
+
|
|
52
|
+
panel.import_metadata_from_file(fname)
|
|
53
|
+
execenv.print("Check metadata export <--> import features:")
|
|
54
|
+
helpers.compare_metadata(
|
|
55
|
+
orig_metadata, ima.metadata, raise_on_diff=True
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
test_metadata_io_unit()
|