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,134 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Add metadata application test for screenshots:
|
|
5
|
+
|
|
6
|
+
- Create signals and images
|
|
7
|
+
- Open Add metadata dialog
|
|
8
|
+
- Take screenshots for documentation
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
12
|
+
# guitest: show
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import warnings
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
|
+
|
|
19
|
+
import guidata.dataset as gds
|
|
20
|
+
|
|
21
|
+
from datalab.env import execenv
|
|
22
|
+
from datalab.gui.panel.base import AddMetadataParam
|
|
23
|
+
from datalab.tests import datalab_test_app_context
|
|
24
|
+
from datalab.tests.features.common.add_metadata_unit_test import (
|
|
25
|
+
create_test_images,
|
|
26
|
+
create_test_signals,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
if TYPE_CHECKING:
|
|
30
|
+
from datalab.gui.main import DLMainWindow
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def __add_metadata_to_signals(win: DLMainWindow, screenshot: bool = False) -> None:
|
|
34
|
+
"""Add metadata to signals helper function."""
|
|
35
|
+
execenv.print("Add metadata signal application test:")
|
|
36
|
+
panel = win.signalpanel
|
|
37
|
+
|
|
38
|
+
# Add test signals to the panel
|
|
39
|
+
for sig in create_test_signals():
|
|
40
|
+
panel.add_object(sig)
|
|
41
|
+
|
|
42
|
+
# Select all signals
|
|
43
|
+
panel.objview.select_objects([1, 2, 3])
|
|
44
|
+
|
|
45
|
+
# Create and configure the Add metadata dialog
|
|
46
|
+
objs = panel.objview.get_sel_objects(include_groups=True)
|
|
47
|
+
param = AddMetadataParam(objs)
|
|
48
|
+
|
|
49
|
+
# Configure example metadata
|
|
50
|
+
param.metadata_key = "experiment_id"
|
|
51
|
+
param.value_pattern = "EXP_{index:03d}"
|
|
52
|
+
param.conversion = "string"
|
|
53
|
+
param.update_preview()
|
|
54
|
+
execenv.print(f" Preview: {param.preview}")
|
|
55
|
+
assert "experiment_id" in param.preview
|
|
56
|
+
execenv.print(" ✓ Add metadata parameter configured correctly")
|
|
57
|
+
|
|
58
|
+
# Edit the parameter to show the dialog
|
|
59
|
+
execenv.print(" Opening Add metadata dialog...")
|
|
60
|
+
with warnings.catch_warnings():
|
|
61
|
+
warnings.simplefilter("ignore", category=gds.DataItemValidationWarning)
|
|
62
|
+
with execenv.context(screenshot=screenshot):
|
|
63
|
+
param.edit(parent=win, wordwrap=False, object_name="s_add_metadata")
|
|
64
|
+
|
|
65
|
+
# Run DataLab's metadata addition functionality:
|
|
66
|
+
panel.add_metadata(param)
|
|
67
|
+
|
|
68
|
+
execenv.print("==> Signal application test OK")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def __add_metadata_to_images(win: DLMainWindow, screenshot: bool = False) -> None:
|
|
72
|
+
"""Add metadata to images helper function."""
|
|
73
|
+
execenv.print("Add metadata image test:")
|
|
74
|
+
panel = win.imagepanel
|
|
75
|
+
|
|
76
|
+
# Add test images to the panel
|
|
77
|
+
for img in create_test_images():
|
|
78
|
+
panel.add_object(img)
|
|
79
|
+
|
|
80
|
+
# Select all images
|
|
81
|
+
panel.objview.select_objects([1, 2, 3])
|
|
82
|
+
|
|
83
|
+
# Create and configure the Add metadata dialog
|
|
84
|
+
objs = panel.objview.get_sel_objects(include_groups=True)
|
|
85
|
+
param = AddMetadataParam(objs)
|
|
86
|
+
|
|
87
|
+
# Configure example metadata
|
|
88
|
+
param.metadata_key = "sample_id"
|
|
89
|
+
param.value_pattern = "SAMPLE_{index:04d}_{title:upper}"
|
|
90
|
+
param.conversion = "string"
|
|
91
|
+
param.update_preview()
|
|
92
|
+
execenv.print(f" Preview: {param.preview}")
|
|
93
|
+
assert "sample_id" in param.preview
|
|
94
|
+
execenv.print(" ✓ Add metadata parameter configured correctly")
|
|
95
|
+
|
|
96
|
+
# Edit the parameter to show the dialog
|
|
97
|
+
execenv.print(" Opening Add metadata dialog...")
|
|
98
|
+
with warnings.catch_warnings():
|
|
99
|
+
warnings.simplefilter("ignore", category=gds.DataItemValidationWarning)
|
|
100
|
+
with execenv.context(screenshot=screenshot):
|
|
101
|
+
param.edit(parent=win, wordwrap=False, object_name="i_add_metadata")
|
|
102
|
+
|
|
103
|
+
# Run DataLab's metadata addition functionality:
|
|
104
|
+
panel.add_metadata(param)
|
|
105
|
+
|
|
106
|
+
execenv.print("==> Image application test OK")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_add_metadata_to_signals() -> None:
|
|
110
|
+
"""Test Add metadata feature for signals."""
|
|
111
|
+
with datalab_test_app_context() as win:
|
|
112
|
+
__add_metadata_to_signals(win)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def test_add_metadata_to_images() -> None:
|
|
116
|
+
"""Test Add metadata feature for images."""
|
|
117
|
+
with datalab_test_app_context() as win:
|
|
118
|
+
__add_metadata_to_images(win)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def add_metadata_screenshots():
|
|
122
|
+
"""Generate add metadata screenshots."""
|
|
123
|
+
with execenv.context(unattended=True):
|
|
124
|
+
with datalab_test_app_context() as win:
|
|
125
|
+
execenv.print("Add metadata screenshots test:")
|
|
126
|
+
__add_metadata_to_signals(win, screenshot=True)
|
|
127
|
+
__add_metadata_to_images(win, screenshot=True)
|
|
128
|
+
execenv.print("==> All screenshot tests completed")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
if __name__ == "__main__":
|
|
132
|
+
# test_add_metadata_to_signals()
|
|
133
|
+
# test_add_metadata_to_images()
|
|
134
|
+
add_metadata_screenshots()
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Unit tests for Add Metadata feature.
|
|
5
|
+
|
|
6
|
+
This module tests the `AddMetadataParam` class and the `add_metadata` method
|
|
7
|
+
from `datalab.gui.panel.base`.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
|
+
|
|
16
|
+
import guidata.config as gcfg
|
|
17
|
+
import numpy as np
|
|
18
|
+
import pytest
|
|
19
|
+
from sigima.objects import create_image, create_signal
|
|
20
|
+
|
|
21
|
+
from datalab.env import execenv
|
|
22
|
+
from datalab.gui.panel.base import AddMetadataParam
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from sigima.objects import ImageObj, SignalObj
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def create_test_signals() -> list[SignalObj]:
|
|
29
|
+
"""Create a list of test signals for testing."""
|
|
30
|
+
# Signal 1: Sine wave
|
|
31
|
+
x = np.linspace(0, 10, 100)
|
|
32
|
+
signal1 = create_signal(
|
|
33
|
+
title="Sine Wave",
|
|
34
|
+
x=x,
|
|
35
|
+
y=np.sin(x),
|
|
36
|
+
metadata={"type": "sine", "frequency": "1 Hz"},
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Signal 2: Cosine wave
|
|
40
|
+
signal2 = create_signal(
|
|
41
|
+
title="Cosine Wave",
|
|
42
|
+
x=x,
|
|
43
|
+
y=np.cos(x * 2),
|
|
44
|
+
metadata={"type": "cosine", "frequency": "2 Hz"},
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Signal 3: Exponential decay
|
|
48
|
+
signal3 = create_signal(
|
|
49
|
+
title="Exponential Decay",
|
|
50
|
+
x=x,
|
|
51
|
+
y=np.exp(-x / 3),
|
|
52
|
+
metadata={"type": "exponential", "time_constant": "3 s"},
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return [signal1, signal2, signal3]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def create_test_images() -> list[ImageObj]:
|
|
59
|
+
"""Create a list of test images for testing."""
|
|
60
|
+
# Image 1: Random noise
|
|
61
|
+
image1 = create_image(
|
|
62
|
+
title="Random Noise",
|
|
63
|
+
data=np.random.rand(100, 100),
|
|
64
|
+
metadata={"type": "noise", "distribution": "uniform"},
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Image 2: Gaussian pattern
|
|
68
|
+
x = np.linspace(-3, 3, 50)
|
|
69
|
+
y = np.linspace(-3, 3, 50)
|
|
70
|
+
X, Y = np.meshgrid(x, y)
|
|
71
|
+
image2 = create_image(
|
|
72
|
+
title="Gaussian Pattern",
|
|
73
|
+
data=np.exp(-(X**2 + Y**2)),
|
|
74
|
+
metadata={"type": "gaussian", "sigma": "1.0"},
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Image 3: Checkerboard pattern
|
|
78
|
+
data3 = np.zeros((100, 100))
|
|
79
|
+
data3[::10, ::10] = 1
|
|
80
|
+
data3[5::10, 5::10] = 1
|
|
81
|
+
image3 = create_image(
|
|
82
|
+
title="Checkerboard",
|
|
83
|
+
data=data3,
|
|
84
|
+
metadata={"type": "pattern", "period": "10 px"},
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return [image1, image2, image3]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TestAddMetadata:
|
|
91
|
+
"""Test class for AddMetadataParam with proper setup/teardown."""
|
|
92
|
+
|
|
93
|
+
@pytest.fixture(autouse=True)
|
|
94
|
+
def setup_validation(self):
|
|
95
|
+
"""Disable guidata validation during tests."""
|
|
96
|
+
old_mode = gcfg.get_validation_mode()
|
|
97
|
+
gcfg.set_validation_mode(gcfg.ValidationMode.DISABLED)
|
|
98
|
+
yield
|
|
99
|
+
gcfg.set_validation_mode(old_mode)
|
|
100
|
+
|
|
101
|
+
def test_string_values(self) -> None:
|
|
102
|
+
"""Test adding string metadata values."""
|
|
103
|
+
execenv.print(f"{self.test_string_values.__doc__}:")
|
|
104
|
+
|
|
105
|
+
# Create test signals
|
|
106
|
+
signals = create_test_signals()
|
|
107
|
+
|
|
108
|
+
# Create parameter
|
|
109
|
+
p = AddMetadataParam(signals)
|
|
110
|
+
p.metadata_key = "test_string"
|
|
111
|
+
p.value_pattern = "{title}"
|
|
112
|
+
p.conversion = "string"
|
|
113
|
+
|
|
114
|
+
# Build values
|
|
115
|
+
values = p.build_values(signals)
|
|
116
|
+
|
|
117
|
+
expected_values = ["Sine Wave", "Cosine Wave", "Exponential Decay"]
|
|
118
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
119
|
+
execenv.print(f" ✓ String values: {values}")
|
|
120
|
+
|
|
121
|
+
# Check preview
|
|
122
|
+
p.update_preview()
|
|
123
|
+
assert "test_string" in p.preview, "Preview should contain metadata key"
|
|
124
|
+
execenv.print(" ✓ Preview generated successfully")
|
|
125
|
+
|
|
126
|
+
execenv.print(f"{self.test_string_values.__doc__}: OK")
|
|
127
|
+
|
|
128
|
+
def test_numeric_values(self) -> None:
|
|
129
|
+
"""Test adding numeric metadata values."""
|
|
130
|
+
execenv.print(f"{self.test_numeric_values.__doc__}:")
|
|
131
|
+
|
|
132
|
+
# Create test signals
|
|
133
|
+
signals = create_test_signals()
|
|
134
|
+
|
|
135
|
+
# Test integer conversion
|
|
136
|
+
p = AddMetadataParam(signals)
|
|
137
|
+
p.metadata_key = "index"
|
|
138
|
+
p.value_pattern = "{index}"
|
|
139
|
+
p.conversion = "int"
|
|
140
|
+
|
|
141
|
+
values = p.build_values(signals)
|
|
142
|
+
expected_values = [1, 2, 3]
|
|
143
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
144
|
+
execenv.print(f" ✓ Integer values: {values}")
|
|
145
|
+
|
|
146
|
+
# Test float conversion
|
|
147
|
+
p.conversion = "float"
|
|
148
|
+
values = p.build_values(signals)
|
|
149
|
+
expected_values = [1.0, 2.0, 3.0]
|
|
150
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
151
|
+
execenv.print(f" ✓ Float values: {values}")
|
|
152
|
+
|
|
153
|
+
execenv.print(f"{self.test_numeric_values.__doc__}: OK")
|
|
154
|
+
|
|
155
|
+
def test_boolean_values(self) -> None:
|
|
156
|
+
"""Test adding boolean metadata values."""
|
|
157
|
+
execenv.print(f"{self.test_boolean_values.__doc__}:")
|
|
158
|
+
|
|
159
|
+
# Create test signals
|
|
160
|
+
signals = create_test_signals()
|
|
161
|
+
|
|
162
|
+
# Test boolean conversion with "true" pattern
|
|
163
|
+
p = AddMetadataParam(signals)
|
|
164
|
+
p.metadata_key = "is_valid"
|
|
165
|
+
p.value_pattern = "true"
|
|
166
|
+
p.conversion = "bool"
|
|
167
|
+
|
|
168
|
+
values = p.build_values(signals)
|
|
169
|
+
expected_values = [True, True, True]
|
|
170
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
171
|
+
execenv.print(f" ✓ Boolean (true) values: {values}")
|
|
172
|
+
|
|
173
|
+
# Test boolean conversion with "false" pattern
|
|
174
|
+
p.value_pattern = "false"
|
|
175
|
+
values = p.build_values(signals)
|
|
176
|
+
expected_values = [False, False, False]
|
|
177
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
178
|
+
execenv.print(f" ✓ Boolean (false) values: {values}")
|
|
179
|
+
|
|
180
|
+
execenv.print(f"{self.test_boolean_values.__doc__}: OK")
|
|
181
|
+
|
|
182
|
+
def test_pattern_formatting(self) -> None:
|
|
183
|
+
"""Test various pattern formatting options."""
|
|
184
|
+
execenv.print(f"{self.test_pattern_formatting.__doc__}:")
|
|
185
|
+
|
|
186
|
+
# Create test signals
|
|
187
|
+
signals = create_test_signals()
|
|
188
|
+
|
|
189
|
+
# Test index with zero padding
|
|
190
|
+
p = AddMetadataParam(signals)
|
|
191
|
+
p.metadata_key = "file_id"
|
|
192
|
+
p.value_pattern = "file_{index:03d}"
|
|
193
|
+
p.conversion = "string"
|
|
194
|
+
|
|
195
|
+
values = p.build_values(signals)
|
|
196
|
+
expected_values = ["file_001", "file_002", "file_003"]
|
|
197
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
198
|
+
execenv.print(f" ✓ Padded index pattern: {values}")
|
|
199
|
+
|
|
200
|
+
# Test uppercase modifier
|
|
201
|
+
p.value_pattern = "{title:upper}"
|
|
202
|
+
values = p.build_values(signals)
|
|
203
|
+
expected_values = ["SINE WAVE", "COSINE WAVE", "EXPONENTIAL DECAY"]
|
|
204
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
205
|
+
execenv.print(f" ✓ Uppercase pattern: {values}")
|
|
206
|
+
|
|
207
|
+
# Test lowercase modifier
|
|
208
|
+
p.value_pattern = "{title:lower}"
|
|
209
|
+
values = p.build_values(signals)
|
|
210
|
+
expected_values = ["sine wave", "cosine wave", "exponential decay"]
|
|
211
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
212
|
+
execenv.print(f" ✓ Lowercase pattern: {values}")
|
|
213
|
+
|
|
214
|
+
execenv.print(f"{self.test_pattern_formatting.__doc__}: OK")
|
|
215
|
+
|
|
216
|
+
def test_with_images(self) -> None:
|
|
217
|
+
"""Test AddMetadataParam with image objects."""
|
|
218
|
+
execenv.print(f"{self.test_with_images.__doc__}:")
|
|
219
|
+
|
|
220
|
+
# Create test images
|
|
221
|
+
images = create_test_images()
|
|
222
|
+
|
|
223
|
+
# Create parameter
|
|
224
|
+
p = AddMetadataParam(images)
|
|
225
|
+
p.metadata_key = "category"
|
|
226
|
+
p.value_pattern = "{title:lower}"
|
|
227
|
+
p.conversion = "string"
|
|
228
|
+
|
|
229
|
+
# Build values
|
|
230
|
+
values = p.build_values(images)
|
|
231
|
+
expected_values = ["random noise", "gaussian pattern", "checkerboard"]
|
|
232
|
+
assert values == expected_values, f"Expected {expected_values}, got {values}"
|
|
233
|
+
execenv.print(f" ✓ Image metadata values: {values}")
|
|
234
|
+
|
|
235
|
+
# Check preview
|
|
236
|
+
p.update_preview()
|
|
237
|
+
assert "category" in p.preview, "Preview should contain metadata key"
|
|
238
|
+
# Check that all values are in the preview
|
|
239
|
+
for expected_val in expected_values:
|
|
240
|
+
assert expected_val in p.preview, f"Preview should contain {expected_val}"
|
|
241
|
+
execenv.print(" ✓ Preview contains all values")
|
|
242
|
+
|
|
243
|
+
execenv.print(f"{self.test_with_images.__doc__}: OK")
|
|
244
|
+
|
|
245
|
+
def test_error_handling(self) -> None:
|
|
246
|
+
"""Test error handling for invalid patterns."""
|
|
247
|
+
execenv.print(f"{self.test_error_handling.__doc__}:")
|
|
248
|
+
|
|
249
|
+
# Create test signals
|
|
250
|
+
signals = create_test_signals()
|
|
251
|
+
|
|
252
|
+
# Test with invalid pattern
|
|
253
|
+
p = AddMetadataParam(signals)
|
|
254
|
+
p.metadata_key = "test"
|
|
255
|
+
p.value_pattern = "{invalid_key}" # This key doesn't exist
|
|
256
|
+
p.conversion = "string"
|
|
257
|
+
|
|
258
|
+
# Update preview should handle the error gracefully
|
|
259
|
+
p.update_preview()
|
|
260
|
+
assert "Invalid" in p.preview, "Preview should show invalid pattern error"
|
|
261
|
+
execenv.print(" ✓ Invalid pattern error handled")
|
|
262
|
+
|
|
263
|
+
execenv.print(f"{self.test_error_handling.__doc__}: OK")
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
if __name__ == "__main__":
|
|
267
|
+
pytest.main([__file__, "-v"])
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""Unit tests for annotation copy/paste functionality."""
|
|
4
|
+
|
|
5
|
+
import os.path as osp
|
|
6
|
+
|
|
7
|
+
from sigima.tests import data as test_data
|
|
8
|
+
|
|
9
|
+
from datalab.env import execenv
|
|
10
|
+
from datalab.tests import datalab_test_app_context, helpers
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_annotations_copy_paste():
|
|
14
|
+
"""Test copying and pasting annotations between objects."""
|
|
15
|
+
with execenv.context(unattended=True):
|
|
16
|
+
with datalab_test_app_context() as win:
|
|
17
|
+
panel = win.signalpanel
|
|
18
|
+
|
|
19
|
+
# Create two signals
|
|
20
|
+
sig1 = test_data.create_paracetamol_signal()
|
|
21
|
+
sig2 = test_data.create_paracetamol_signal()
|
|
22
|
+
|
|
23
|
+
# Add annotations to first signal
|
|
24
|
+
orig_annotations = [
|
|
25
|
+
{"type": "label", "text": "Peak 1"},
|
|
26
|
+
{"type": "label", "text": "Peak 2"},
|
|
27
|
+
]
|
|
28
|
+
sig1.set_annotations(orig_annotations)
|
|
29
|
+
|
|
30
|
+
# Add objects to panel - sig1 will be selected after this
|
|
31
|
+
panel.add_object(sig1)
|
|
32
|
+
|
|
33
|
+
# Copy from first signal (which is currently selected)
|
|
34
|
+
panel.copy_annotations()
|
|
35
|
+
|
|
36
|
+
# Add second signal - sig2 will be selected after this
|
|
37
|
+
panel.add_object(sig2)
|
|
38
|
+
|
|
39
|
+
# Paste to second signal (which is now selected)
|
|
40
|
+
panel.paste_annotations()
|
|
41
|
+
|
|
42
|
+
# Verify annotations were copied
|
|
43
|
+
assert sig2.get_annotations() == orig_annotations
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_annotations_import_export():
|
|
47
|
+
"""Test importing and exporting annotations to file."""
|
|
48
|
+
with execenv.context(unattended=True):
|
|
49
|
+
with helpers.WorkdirRestoringTempDir() as tmpdir:
|
|
50
|
+
fname = osp.join(tmpdir, "test.dlabann")
|
|
51
|
+
with datalab_test_app_context() as win:
|
|
52
|
+
panel = win.signalpanel
|
|
53
|
+
|
|
54
|
+
# Create signal with annotations
|
|
55
|
+
sig = test_data.create_paracetamol_signal()
|
|
56
|
+
orig_annotations = [{"type": "label", "text": "Test annotation"}]
|
|
57
|
+
sig.set_annotations(orig_annotations)
|
|
58
|
+
|
|
59
|
+
panel.add_object(sig)
|
|
60
|
+
|
|
61
|
+
# Export annotations
|
|
62
|
+
panel.export_annotations_from_file(fname)
|
|
63
|
+
|
|
64
|
+
# Clear annotations to test import
|
|
65
|
+
sig.clear_annotations()
|
|
66
|
+
assert len(sig.get_annotations()) == 0
|
|
67
|
+
|
|
68
|
+
# Import annotations
|
|
69
|
+
panel.import_annotations_from_file(fname)
|
|
70
|
+
|
|
71
|
+
# Verify annotations were imported
|
|
72
|
+
assert sig.get_annotations() == orig_annotations
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_annotations_delete():
|
|
76
|
+
"""Test deleting annotations from objects."""
|
|
77
|
+
with execenv.context(unattended=True):
|
|
78
|
+
with datalab_test_app_context() as win:
|
|
79
|
+
panel = win.signalpanel
|
|
80
|
+
|
|
81
|
+
# Create signal with annotations
|
|
82
|
+
sig = test_data.create_paracetamol_signal()
|
|
83
|
+
sig.set_annotations(
|
|
84
|
+
[
|
|
85
|
+
{"type": "label", "text": "To be deleted"},
|
|
86
|
+
]
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
panel.add_object(sig)
|
|
90
|
+
|
|
91
|
+
# Verify annotations exist
|
|
92
|
+
assert len(sig.get_annotations()) == 1
|
|
93
|
+
|
|
94
|
+
# Delete annotations
|
|
95
|
+
panel.delete_annotations()
|
|
96
|
+
|
|
97
|
+
# Verify annotations were deleted
|
|
98
|
+
assert len(sig.get_annotations()) == 0
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_annotations_action_states():
|
|
102
|
+
"""Test that action states are updated after annotation operations.
|
|
103
|
+
|
|
104
|
+
This test verifies the fix for the issue where action enable states
|
|
105
|
+
were not updated after operations like delete_annotations, requiring
|
|
106
|
+
the user to select another object for the actions to update.
|
|
107
|
+
|
|
108
|
+
Note: We can't easily test the UI action states in automated tests,
|
|
109
|
+
but we verify that the underlying state update mechanism is called.
|
|
110
|
+
"""
|
|
111
|
+
with execenv.context(unattended=True):
|
|
112
|
+
with datalab_test_app_context() as win:
|
|
113
|
+
panel = win.signalpanel
|
|
114
|
+
|
|
115
|
+
# Create signal with annotations
|
|
116
|
+
sig = test_data.create_paracetamol_signal()
|
|
117
|
+
orig_annotations = [{"type": "label", "text": "Test"}]
|
|
118
|
+
sig.set_annotations(orig_annotations)
|
|
119
|
+
|
|
120
|
+
panel.add_object(sig)
|
|
121
|
+
|
|
122
|
+
# Verify object has annotations
|
|
123
|
+
assert len(sig.get_annotations()) == 1
|
|
124
|
+
|
|
125
|
+
# Delete annotations - this should update action states
|
|
126
|
+
panel.delete_annotations()
|
|
127
|
+
|
|
128
|
+
# Verify annotations were deleted
|
|
129
|
+
assert len(sig.get_annotations()) == 0
|
|
130
|
+
|
|
131
|
+
# Verify clipboard is empty
|
|
132
|
+
assert len(panel.annotations_clipboard) == 0
|
|
133
|
+
|
|
134
|
+
# Re-add annotations and copy - this should update action states
|
|
135
|
+
sig.set_annotations(orig_annotations)
|
|
136
|
+
panel.selection_changed() # Refresh states
|
|
137
|
+
panel.copy_annotations()
|
|
138
|
+
|
|
139
|
+
# Verify clipboard now has annotations
|
|
140
|
+
assert len(panel.annotations_clipboard) == 1
|
|
141
|
+
|
|
142
|
+
# Clear annotations, paste, and verify
|
|
143
|
+
sig.clear_annotations()
|
|
144
|
+
panel.paste_annotations()
|
|
145
|
+
assert len(sig.get_annotations()) == 1
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
if __name__ == "__main__":
|
|
149
|
+
test_annotations_copy_paste()
|
|
150
|
+
test_annotations_import_export()
|
|
151
|
+
test_annotations_delete()
|
|
152
|
+
test_annotations_action_states()
|