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,392 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Operation modes test
|
|
5
|
+
--------------------
|
|
6
|
+
|
|
7
|
+
DataLab has two operation modes:
|
|
8
|
+
|
|
9
|
+
- **Single operand mode**: the operation is applied to the selected objects (this
|
|
10
|
+
is the default mode)
|
|
11
|
+
|
|
12
|
+
- **Pairwise mode**: the operation is applied to the selected pairs of objects
|
|
13
|
+
|
|
14
|
+
This test scenario covers the pairwise mode and the operations that can be
|
|
15
|
+
performed in this mode: sum, difference, product, division, ...
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# guitest: show
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from datalab import app
|
|
23
|
+
from datalab.config import Conf
|
|
24
|
+
from datalab.env import execenv
|
|
25
|
+
from datalab.gui.processor.base import is_pairwise_mode
|
|
26
|
+
from datalab.objectmodel import get_short_id
|
|
27
|
+
from datalab.tests import helpers
|
|
28
|
+
from datalab.utils.qthelpers import datalab_app_context
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_h5fname() -> str:
|
|
32
|
+
"""Get the HDF5 test filename"""
|
|
33
|
+
fnames = helpers.get_test_fnames("reorder*")
|
|
34
|
+
return fnames[0]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def check_titles(title: str, titles: list[tuple[str, str]]) -> None:
|
|
38
|
+
"""Check that the title is one of the expected titles"""
|
|
39
|
+
execenv.print(f"{title}:")
|
|
40
|
+
for actual_title, expected_title in titles:
|
|
41
|
+
execenv.print(f" {actual_title} == {expected_title}", end=" ")
|
|
42
|
+
assert actual_title == expected_title
|
|
43
|
+
if actual_title == expected_title:
|
|
44
|
+
execenv.print("✓")
|
|
45
|
+
else:
|
|
46
|
+
execenv.print("✗")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_single_operand_mode_compute_n_to_1() -> None:
|
|
50
|
+
"""Run single operand mode test scenario
|
|
51
|
+
with `compute_n_to_1` operation (e.g. sum)"""
|
|
52
|
+
h5fname = get_h5fname()
|
|
53
|
+
original_mode = Conf.proc.operation_mode.get()
|
|
54
|
+
Conf.proc.operation_mode.set("single")
|
|
55
|
+
|
|
56
|
+
with datalab_app_context(exec_loop=True):
|
|
57
|
+
win = app.create(h5files=[h5fname], console=False)
|
|
58
|
+
panel = win.signalpanel
|
|
59
|
+
view, model = panel.objview, panel.objmodel
|
|
60
|
+
|
|
61
|
+
# Checking the operation mode:
|
|
62
|
+
assert not is_pairwise_mode()
|
|
63
|
+
|
|
64
|
+
# Store the number of groups before the operations
|
|
65
|
+
n_groups = len(model.get_groups())
|
|
66
|
+
|
|
67
|
+
# Select the two first groups
|
|
68
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
69
|
+
view.select_groups(groups)
|
|
70
|
+
|
|
71
|
+
# Perform a sum operation
|
|
72
|
+
panel.processor.run_feature("addition")
|
|
73
|
+
|
|
74
|
+
# Default operation mode is single operand mode, so the sum operation
|
|
75
|
+
# is applied to the selected groups, and we should have a new group
|
|
76
|
+
# with two signals being the sum of signals from each group:
|
|
77
|
+
# - signal 1: group 1 signal 1 + group 1 signal 2
|
|
78
|
+
# - signal 2: group 2 signal 1 + group 2 signal 2
|
|
79
|
+
assert len(model.get_groups()) == n_groups + 1
|
|
80
|
+
new_group = model.get_group_from_number(n_groups + 1)
|
|
81
|
+
assert len(new_group) == 2
|
|
82
|
+
titles = []
|
|
83
|
+
for idx, obj in enumerate(new_group):
|
|
84
|
+
pfx_orig = ", ".join(get_short_id(obj) for obj in groups[idx].get_objects())
|
|
85
|
+
titles.append((obj.title, f"Σ({pfx_orig})"))
|
|
86
|
+
check_titles(f"Single operand mode Σ[{new_group.title}]", titles)
|
|
87
|
+
|
|
88
|
+
# Remove new group
|
|
89
|
+
view.select_groups([new_group])
|
|
90
|
+
panel.remove_object(force=True)
|
|
91
|
+
|
|
92
|
+
# Store the number of groups before the operations
|
|
93
|
+
n_groups = len(model.get_groups())
|
|
94
|
+
|
|
95
|
+
# Select the two first signals of the first two groups
|
|
96
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
97
|
+
objs = groups[0][:2] + groups[1][:2]
|
|
98
|
+
view.select_objects(objs)
|
|
99
|
+
|
|
100
|
+
# Perform a sum operation
|
|
101
|
+
panel.processor.run_feature("addition")
|
|
102
|
+
|
|
103
|
+
# Default operation mode is single operand mode, so the sum operation
|
|
104
|
+
# is applied to the selected signals, and we should have a new resulting
|
|
105
|
+
# signal being the sum of the selected signals added in each group:
|
|
106
|
+
# - signal added to group 1: group 1 signal 1 + group 2 signal 1
|
|
107
|
+
# - signal added to group 2: group 1 signal 2 + group 2 signal 2
|
|
108
|
+
assert len(model.get_groups()) == n_groups # no new group
|
|
109
|
+
titles = []
|
|
110
|
+
for idx in range(1):
|
|
111
|
+
pfx_orig = ", ".join(get_short_id(obj) for obj in groups[idx][:2])
|
|
112
|
+
titles.append((groups[idx][-1].title, f"Σ({pfx_orig})"))
|
|
113
|
+
check_titles(f"Single operand mode Σ[{groups[1].title}]", titles)
|
|
114
|
+
|
|
115
|
+
Conf.proc.operation_mode.set(original_mode)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_pairwise_operations_mode_compute_n_to_1() -> None:
|
|
119
|
+
"""Run pairwise operations mode test scenario
|
|
120
|
+
with `compute_n_to_1` operation (e.g. sum)"""
|
|
121
|
+
h5fname = get_h5fname()
|
|
122
|
+
original_mode = Conf.proc.operation_mode.get()
|
|
123
|
+
Conf.proc.operation_mode.set("pairwise")
|
|
124
|
+
|
|
125
|
+
with datalab_app_context(exec_loop=True):
|
|
126
|
+
win = app.create(h5files=[h5fname], console=False)
|
|
127
|
+
panel = win.signalpanel
|
|
128
|
+
view, model = panel.objview, panel.objmodel
|
|
129
|
+
|
|
130
|
+
# Checking the operation mode:
|
|
131
|
+
assert is_pairwise_mode()
|
|
132
|
+
|
|
133
|
+
# Store the number of groups before the operations
|
|
134
|
+
n_groups = len(model.get_groups())
|
|
135
|
+
|
|
136
|
+
# Select the two first groups
|
|
137
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
138
|
+
view.select_groups(groups)
|
|
139
|
+
|
|
140
|
+
# Checking that each group contains the same number of signals (this is
|
|
141
|
+
# required for pairwise operations - this part of the test is checking
|
|
142
|
+
# if the data file is the one we expect)
|
|
143
|
+
n_objects = len(groups[0])
|
|
144
|
+
assert all(len(group) == n_objects for group in groups)
|
|
145
|
+
|
|
146
|
+
# Perform a sum operation
|
|
147
|
+
panel.processor.run_feature("addition")
|
|
148
|
+
|
|
149
|
+
# Operation mode is now pairwise, so the sum operation is applied to the
|
|
150
|
+
# selected groups, and we should have a new group with as many signals as
|
|
151
|
+
# the original groups, each signal being the sum of the corresponding signals:
|
|
152
|
+
# - signal 1: group 1 signal 1 + group 2 signal 1
|
|
153
|
+
# - signal 2: group 1 signal 1 + group 2 signal 2
|
|
154
|
+
# ...
|
|
155
|
+
assert len(model.get_groups()) == n_groups + 1
|
|
156
|
+
new_group = model.get_group_from_number(n_groups + 1)
|
|
157
|
+
assert len(new_group.get_objects()) == n_objects
|
|
158
|
+
titles = []
|
|
159
|
+
for idx in range(len(groups[0])):
|
|
160
|
+
obj = new_group[idx]
|
|
161
|
+
pfx_orig = ", ".join(
|
|
162
|
+
get_short_id(obj) for obj in (grp[idx] for grp in groups)
|
|
163
|
+
)
|
|
164
|
+
titles.append((obj.title, f"Σ({pfx_orig})"))
|
|
165
|
+
check_titles(f"Pairwise operations mode Σ[{new_group.title}]", titles)
|
|
166
|
+
|
|
167
|
+
# Remove new group
|
|
168
|
+
view.select_groups([new_group])
|
|
169
|
+
panel.remove_object(force=True)
|
|
170
|
+
|
|
171
|
+
# Store the number of groups before the operations
|
|
172
|
+
n_groups = len(model.get_groups())
|
|
173
|
+
|
|
174
|
+
# Select two signals of the first two groups
|
|
175
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
176
|
+
objs = [groups[0][0]] + [groups[0][-1]] + groups[1][-2:]
|
|
177
|
+
view.select_objects(objs)
|
|
178
|
+
|
|
179
|
+
# Perform a sum operation
|
|
180
|
+
panel.processor.run_feature("addition")
|
|
181
|
+
|
|
182
|
+
# Operation mode is now pairwise, so the sum operation is applied to the
|
|
183
|
+
# selected signals, and we should have a new group with as many signals as
|
|
184
|
+
# the selected signals, each signal being the sum of the corresponding signals:
|
|
185
|
+
# - signal 1: group 1 signal 1 + group 2 signal 1
|
|
186
|
+
# - signal 2: group 1 signal 1 + group 2 signal 2
|
|
187
|
+
# ...
|
|
188
|
+
assert len(model.get_groups()) == n_groups + 1
|
|
189
|
+
new_group = model.get_group_from_number(n_groups + 1)
|
|
190
|
+
assert len(new_group) == 2 # 2 signals were selected
|
|
191
|
+
titles = []
|
|
192
|
+
for idx, obj in enumerate(new_group):
|
|
193
|
+
pfx_orig = ", ".join(get_short_id(obj) for obj in objs[idx::2])
|
|
194
|
+
titles.append((obj.title, f"Σ({pfx_orig})"))
|
|
195
|
+
check_titles(f"Pairwise operations mode Σ[{new_group.title}]", titles)
|
|
196
|
+
|
|
197
|
+
Conf.proc.operation_mode.set(original_mode)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def test_single_operand_mode_compute_2_to_1() -> None:
|
|
201
|
+
"""Run single operand mode test scenario
|
|
202
|
+
with `compute_2_to_1` operation (e.g. difference)"""
|
|
203
|
+
h5fname = get_h5fname()
|
|
204
|
+
original_mode = Conf.proc.operation_mode.get()
|
|
205
|
+
Conf.proc.operation_mode.set("single")
|
|
206
|
+
|
|
207
|
+
with datalab_app_context(exec_loop=True):
|
|
208
|
+
win = app.create(h5files=[h5fname], console=False)
|
|
209
|
+
panel = win.signalpanel
|
|
210
|
+
view, model = panel.objview, panel.objmodel
|
|
211
|
+
|
|
212
|
+
# Checking the operation mode:
|
|
213
|
+
assert not is_pairwise_mode()
|
|
214
|
+
|
|
215
|
+
# Store the number of groups before the operations
|
|
216
|
+
n_groups = len(model.get_groups())
|
|
217
|
+
|
|
218
|
+
# Select the two first groups
|
|
219
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
220
|
+
view.select_groups(groups)
|
|
221
|
+
n_objects = [len(grp) for grp in groups]
|
|
222
|
+
|
|
223
|
+
# Perform a difference operation with the first signal of the third group
|
|
224
|
+
group3 = model.get_group_from_number(3)
|
|
225
|
+
panel.processor.run_feature("difference", group3[0])
|
|
226
|
+
|
|
227
|
+
# Default operation mode is single operand mode, so we should have new signals
|
|
228
|
+
# in each selected group being the difference between the original signals and
|
|
229
|
+
# the selected signal:
|
|
230
|
+
# - in group 1:
|
|
231
|
+
# - signal 1: group 1 signal 1 - group 3 signal 1
|
|
232
|
+
# - signal 2: group 1 signal 2 - group 3 signal 1
|
|
233
|
+
# - in group 2:
|
|
234
|
+
# - signal 1: group 2 signal 1 - group 3 signal 1
|
|
235
|
+
# - signal 2: group 2 signal 2 - group 3 signal 1
|
|
236
|
+
assert len(model.get_groups()) == n_groups
|
|
237
|
+
new_objs = []
|
|
238
|
+
for i_group, group in enumerate(groups):
|
|
239
|
+
titles = []
|
|
240
|
+
for i_obj in range(n_objects[i_group]):
|
|
241
|
+
obj = group[i_obj + n_objects[i_group]]
|
|
242
|
+
titles.append(
|
|
243
|
+
(
|
|
244
|
+
obj.title,
|
|
245
|
+
f"{get_short_id(group[i_obj])}-{get_short_id(group3[0])}",
|
|
246
|
+
)
|
|
247
|
+
)
|
|
248
|
+
new_objs.append(obj)
|
|
249
|
+
check_titles(f"Single operand mode Δ[{group.title}]", titles)
|
|
250
|
+
|
|
251
|
+
# Remove new signals
|
|
252
|
+
view.select_objects(new_objs)
|
|
253
|
+
panel.remove_object(force=True)
|
|
254
|
+
|
|
255
|
+
# Store the number of groups before the operations
|
|
256
|
+
n_groups = len(model.get_groups())
|
|
257
|
+
|
|
258
|
+
# Select the two first signals of the first two groups
|
|
259
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
260
|
+
objs = groups[0][:2] + groups[1][:2]
|
|
261
|
+
view.select_objects(objs)
|
|
262
|
+
n_objects = [2, 2]
|
|
263
|
+
|
|
264
|
+
# Perform a difference operation with the first signal of the third group
|
|
265
|
+
panel.processor.run_feature("difference", group3[0])
|
|
266
|
+
|
|
267
|
+
# Default operation mode is single operand mode, so we should have new signals
|
|
268
|
+
# being the difference between the original signals and the selected signal:
|
|
269
|
+
# - in group 1:
|
|
270
|
+
# - signal 1: group 1 signal 1 - group 3 signal 1
|
|
271
|
+
# - signal 2: group 1 signal 2 - group 3 signal 1
|
|
272
|
+
# - in group 2:
|
|
273
|
+
# - signal 1: group 2 signal 1 - group 3 signal 1
|
|
274
|
+
# - signal 2: group 2 signal 2 - group 3 signal 1
|
|
275
|
+
assert len(model.get_groups()) == n_groups # no new group
|
|
276
|
+
for i_group, group in enumerate(groups):
|
|
277
|
+
titles = []
|
|
278
|
+
for i_obj in range(n_objects[i_group]):
|
|
279
|
+
obj = group[len(group) - n_objects[i_group] + i_obj]
|
|
280
|
+
titles.append(
|
|
281
|
+
(
|
|
282
|
+
obj.title,
|
|
283
|
+
f"{get_short_id(group[i_obj])}-{get_short_id(group3[0])}",
|
|
284
|
+
)
|
|
285
|
+
)
|
|
286
|
+
check_titles(f"Single operand mode Δ[{group.title}]", titles)
|
|
287
|
+
|
|
288
|
+
Conf.proc.operation_mode.set(original_mode)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def test_pairwise_operations_mode_compute_2_to_1() -> None:
|
|
292
|
+
"""Run pairwise operations mode test scenario
|
|
293
|
+
with `compute_2_to_1` operation (e.g. difference)"""
|
|
294
|
+
h5fname = get_h5fname()
|
|
295
|
+
original_mode = Conf.proc.operation_mode.get()
|
|
296
|
+
Conf.proc.operation_mode.set("pairwise")
|
|
297
|
+
|
|
298
|
+
with datalab_app_context(exec_loop=True):
|
|
299
|
+
win = app.create(h5files=[h5fname], console=False)
|
|
300
|
+
panel = win.signalpanel
|
|
301
|
+
view, model = panel.objview, panel.objmodel
|
|
302
|
+
|
|
303
|
+
# Checking the operation mode:
|
|
304
|
+
assert is_pairwise_mode()
|
|
305
|
+
|
|
306
|
+
# Store the number of groups before the operations
|
|
307
|
+
n_groups = len(model.get_groups())
|
|
308
|
+
|
|
309
|
+
# Select the two first groups
|
|
310
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
311
|
+
view.select_groups(groups)
|
|
312
|
+
|
|
313
|
+
# Checking that each group contains the same number of signals (this is
|
|
314
|
+
# required for pairwise operations - this part of the test is checking
|
|
315
|
+
# if the data file is the one we expect)
|
|
316
|
+
n_objects = len(groups[0])
|
|
317
|
+
assert all(len(group) == n_objects for group in groups)
|
|
318
|
+
|
|
319
|
+
# Perform a difference operation with the third group
|
|
320
|
+
group3 = model.get_group_from_number(3)
|
|
321
|
+
assert len(group3) == n_objects
|
|
322
|
+
panel.processor.run_feature("difference", group3.get_objects())
|
|
323
|
+
|
|
324
|
+
# Operation mode is now pairwise, so the difference operation is applied to the
|
|
325
|
+
# selected groups, and we should have a new group with as many signals as the
|
|
326
|
+
# original groups, each signal being the difference of the corresponding
|
|
327
|
+
# signals:
|
|
328
|
+
# - signal 1: group 1 signal 1 - group 2 signal 1
|
|
329
|
+
# - signal 2: group 1 signal 1 - group 2 signal 2
|
|
330
|
+
# ...
|
|
331
|
+
assert len(model.get_groups()) == n_groups + 2
|
|
332
|
+
new_groups = [
|
|
333
|
+
model.get_group_from_number(idx) for idx in (n_groups + 1, n_groups + 2)
|
|
334
|
+
]
|
|
335
|
+
execenv.print("Δ|pairwise")
|
|
336
|
+
for i_new_grp, new_grp in enumerate(new_groups):
|
|
337
|
+
assert len(new_grp.get_objects()) == n_objects
|
|
338
|
+
titles = []
|
|
339
|
+
for idx in range(n_objects):
|
|
340
|
+
obj = new_grp[idx]
|
|
341
|
+
obj1, obj2 = groups[i_new_grp][idx], group3[idx]
|
|
342
|
+
titles.append((obj.title, f"{get_short_id(obj1)}-{get_short_id(obj2)}"))
|
|
343
|
+
check_titles(f"Pairwise operations mode Δ[{new_grp.title}]", titles)
|
|
344
|
+
|
|
345
|
+
# Remove new groups
|
|
346
|
+
view.select_groups(new_groups)
|
|
347
|
+
panel.remove_object(force=True)
|
|
348
|
+
|
|
349
|
+
# Store the number of groups before the operations
|
|
350
|
+
n_groups = len(model.get_groups())
|
|
351
|
+
|
|
352
|
+
# Select two signals of the first two groups
|
|
353
|
+
groups = [model.get_group_from_number(idx) for idx in (1, 2)]
|
|
354
|
+
objs = [groups[0][0]] + [groups[0][-1]] + groups[1][-2:]
|
|
355
|
+
view.select_objects(objs)
|
|
356
|
+
n_objects = 2
|
|
357
|
+
|
|
358
|
+
# Perform a difference operation with two signals from the third group
|
|
359
|
+
objs2 = group3[:2]
|
|
360
|
+
panel.processor.run_feature("difference", objs2)
|
|
361
|
+
|
|
362
|
+
# Operation mode is now pairwise, so the difference operation is applied to the
|
|
363
|
+
# selected signals, and we should have a new group with as many signals as the
|
|
364
|
+
# selected signals, each signal being the difference of the corresponding
|
|
365
|
+
# signals:
|
|
366
|
+
# - signal 1: group 1 signal 1 - group 3 signal 1
|
|
367
|
+
# - signal 2: group 1 signal 1 - group 3 signal 2
|
|
368
|
+
# ...
|
|
369
|
+
assert len(model.get_groups()) == n_groups + 2
|
|
370
|
+
new_groups = [
|
|
371
|
+
model.get_group_from_number(idx) for idx in (n_groups + 1, n_groups + 2)
|
|
372
|
+
]
|
|
373
|
+
i_obj1 = 0
|
|
374
|
+
execenv.print("Δ|pairwise")
|
|
375
|
+
for i_new_grp, new_grp in enumerate(new_groups):
|
|
376
|
+
assert len(new_grp.get_objects()) == n_objects
|
|
377
|
+
titles = []
|
|
378
|
+
for idx in range(n_objects):
|
|
379
|
+
obj = new_grp[idx]
|
|
380
|
+
obj1, obj2 = objs[i_obj1], objs2[idx]
|
|
381
|
+
i_obj1 += 1
|
|
382
|
+
titles.append((obj.title, f"{get_short_id(obj1)}-{get_short_id(obj2)}"))
|
|
383
|
+
check_titles(f"Pairwise operations mode Δ[{new_grp.title}]", titles)
|
|
384
|
+
|
|
385
|
+
Conf.proc.operation_mode.set(original_mode)
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
if __name__ == "__main__":
|
|
389
|
+
test_single_operand_mode_compute_n_to_1()
|
|
390
|
+
test_pairwise_operations_mode_compute_n_to_1()
|
|
391
|
+
test_single_operand_mode_compute_2_to_1()
|
|
392
|
+
test_pairwise_operations_mode_compute_2_to_1()
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Plot results application test:
|
|
5
|
+
|
|
6
|
+
Testing the "Plot results" feature with different options:
|
|
7
|
+
- Different plot kinds (one curve per object vs. one curve per title)
|
|
8
|
+
- Different X/Y axis selections
|
|
9
|
+
- Results with and without ROIs
|
|
10
|
+
- Both signal and image panels
|
|
11
|
+
- Multiple result types (scalar and geometry results)
|
|
12
|
+
- Group selection creates a new result group
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# guitest: show
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Generator
|
|
20
|
+
|
|
21
|
+
import sigima.objects
|
|
22
|
+
import sigima.params
|
|
23
|
+
from sigima.tests import data as test_data
|
|
24
|
+
|
|
25
|
+
from datalab.config import _
|
|
26
|
+
from datalab.env import execenv
|
|
27
|
+
from datalab.objectmodel import get_uuid
|
|
28
|
+
from datalab.tests import datalab_test_app_context
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def iterate_noisy_signals(
|
|
32
|
+
count: int,
|
|
33
|
+
a: float,
|
|
34
|
+
sigma: float,
|
|
35
|
+
) -> Generator[tuple[sigima.objects.SignalObj, float], None, None]:
|
|
36
|
+
"""Generate noisy signals for testing."""
|
|
37
|
+
noiseparam = sigima.objects.NormalDistribution1DParam.create(sigma=sigma, mu=0.0)
|
|
38
|
+
param = sigima.objects.GaussParam.create(a=a)
|
|
39
|
+
for i in range(count):
|
|
40
|
+
param.sigma = 1.0 + (i * 0.1) ** 2
|
|
41
|
+
theoretical_fwhm = param.get_expected_features().fwhm
|
|
42
|
+
sig = test_data.create_noisy_signal(
|
|
43
|
+
noiseparam, param, f"Signal|fwhm_th={theoretical_fwhm:.2f}"
|
|
44
|
+
)
|
|
45
|
+
yield sig, theoretical_fwhm
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_plot_results_signals_one_curve_per_title():
|
|
49
|
+
"""Test plot results feature with signals, one curve per title.
|
|
50
|
+
|
|
51
|
+
Create signals with single-value results (e.g., FWHM) and plot them.
|
|
52
|
+
Verify that results are created in the "Results" group.
|
|
53
|
+
"""
|
|
54
|
+
with datalab_test_app_context() as win:
|
|
55
|
+
panel = win.signalpanel
|
|
56
|
+
|
|
57
|
+
with execenv.context(unattended=True):
|
|
58
|
+
x_th = []
|
|
59
|
+
y_th = []
|
|
60
|
+
for i, (sig, theoretical_fwhm) in enumerate(
|
|
61
|
+
iterate_noisy_signals(5, a=10.0, sigma=0.01)
|
|
62
|
+
):
|
|
63
|
+
x_th.append(i)
|
|
64
|
+
y_th.append(theoretical_fwhm)
|
|
65
|
+
panel.add_object(sig)
|
|
66
|
+
# Compute FWHM using the default method (zero-crossing) which introduces
|
|
67
|
+
# a systematic ~2% error compared to the theoretical value
|
|
68
|
+
# (trade-off for noise robustness)
|
|
69
|
+
panel.processor.run_feature("fwhm", sigima.params.FWHMParam())
|
|
70
|
+
|
|
71
|
+
# Get number of groups before plotting
|
|
72
|
+
groups_before = len(panel.objmodel.get_groups())
|
|
73
|
+
|
|
74
|
+
panel.objview.selectAll()
|
|
75
|
+
panel.show_results()
|
|
76
|
+
panel.plot_results(kind="one_curve_per_title", xaxis="indices", yaxis="Δx")
|
|
77
|
+
|
|
78
|
+
# Verify a Results group was created
|
|
79
|
+
groups_after = panel.objmodel.get_groups()
|
|
80
|
+
assert len(groups_after) == groups_before + 1, (
|
|
81
|
+
f"Expected {groups_before + 1} groups, got {len(groups_after)}"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Verify the new group is named "Results"
|
|
85
|
+
expected_title = _("Results")
|
|
86
|
+
result_group = groups_after[-1]
|
|
87
|
+
assert result_group.title == expected_title, (
|
|
88
|
+
f"Expected last group to be '{expected_title}', "
|
|
89
|
+
f"got '{result_group.title}'"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Verify the Results group contains the result signal
|
|
93
|
+
assert len(result_group) > 0, (
|
|
94
|
+
"Results group should contain at least one result signal"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
fwhm_var_th = sigima.objects.create_signal("FWHM_Theoretical", x_th, y_th)
|
|
98
|
+
panel.add_object(fwhm_var_th)
|
|
99
|
+
panel.objview.select_objects((6, 7))
|
|
100
|
+
# The observed offset should be around ~2% of the theoretical value
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_plot_results_images_one_curve_per_object():
|
|
104
|
+
"""Test plot results feature with images, one curve per object.
|
|
105
|
+
|
|
106
|
+
Create images with multi-value results (e.g., peak detection) and plot them.
|
|
107
|
+
"""
|
|
108
|
+
with datalab_test_app_context() as win:
|
|
109
|
+
panel = win.imagepanel
|
|
110
|
+
|
|
111
|
+
with execenv.context(unattended=True):
|
|
112
|
+
for i in range(3):
|
|
113
|
+
img = test_data.create_peak_image()
|
|
114
|
+
img.title = f"Peaks_{i + 1}"
|
|
115
|
+
panel.add_object(img)
|
|
116
|
+
param = sigima.params.Peak2DDetectionParam.create(create_rois=False)
|
|
117
|
+
panel.processor.run_feature("peak_detection", param)
|
|
118
|
+
|
|
119
|
+
panel.objview.selectAll()
|
|
120
|
+
panel.show_results()
|
|
121
|
+
# Use programmatic parameters: plot y vs x for each peak
|
|
122
|
+
panel.plot_results(kind="one_curve_per_object", xaxis="x", yaxis="y")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_plot_results_images_with_rois():
|
|
126
|
+
"""Test plot results feature with images containing ROIs.
|
|
127
|
+
|
|
128
|
+
Create images with ROIs and single-value results (e.g., centroid) and plot them.
|
|
129
|
+
"""
|
|
130
|
+
with datalab_test_app_context() as win:
|
|
131
|
+
panel = win.imagepanel
|
|
132
|
+
|
|
133
|
+
with execenv.context(unattended=True):
|
|
134
|
+
size = 512
|
|
135
|
+
peak_param = test_data.PeakDataParam.create(size=size)
|
|
136
|
+
for i in range(3):
|
|
137
|
+
data, peak_coords = test_data.get_peak2d_data(peak_param)
|
|
138
|
+
img = sigima.objects.create_image(f"Image_ROI_{i + 1}", data)
|
|
139
|
+
# Add rectangular ROI to image
|
|
140
|
+
roi_coords = []
|
|
141
|
+
for xpeak, ypeak in peak_coords:
|
|
142
|
+
roi_coords.append([xpeak, ypeak, 20])
|
|
143
|
+
img.roi = sigima.objects.create_image_roi("circle", roi_coords)
|
|
144
|
+
panel.add_object(img)
|
|
145
|
+
panel.processor.run_feature("centroid")
|
|
146
|
+
|
|
147
|
+
panel.objview.selectAll()
|
|
148
|
+
panel.show_results()
|
|
149
|
+
# Plot centroid x vs indices with ROIs
|
|
150
|
+
panel.plot_results(kind="one_curve_per_title", xaxis="indices", yaxis="x")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_plot_results_with_group_selection():
|
|
154
|
+
"""Test plot results with Results group.
|
|
155
|
+
|
|
156
|
+
All plot results operations should create result signals in a reusable
|
|
157
|
+
"Results" group for better organization.
|
|
158
|
+
"""
|
|
159
|
+
with datalab_test_app_context() as win:
|
|
160
|
+
panel = win.signalpanel
|
|
161
|
+
|
|
162
|
+
with execenv.context(unattended=True):
|
|
163
|
+
# Create a group with signals
|
|
164
|
+
panel.add_group("Test Group")
|
|
165
|
+
|
|
166
|
+
# Add signals and compute FWHM
|
|
167
|
+
for i, (sig, _fwhm) in enumerate(
|
|
168
|
+
iterate_noisy_signals(3, a=10.0, sigma=0.01)
|
|
169
|
+
):
|
|
170
|
+
sig.title = f"Signal_{i + 1}"
|
|
171
|
+
panel.add_object(sig)
|
|
172
|
+
panel.processor.run_feature("fwhm", sigima.params.FWHMParam())
|
|
173
|
+
|
|
174
|
+
# Get the number of groups before plotting results
|
|
175
|
+
groups_before = len(panel.objmodel.get_groups())
|
|
176
|
+
|
|
177
|
+
# Select the group (not individual objects)
|
|
178
|
+
panel.objview.select_groups([1])
|
|
179
|
+
|
|
180
|
+
# Verify the group is selected
|
|
181
|
+
sel_groups = panel.objview.get_sel_groups()
|
|
182
|
+
assert len(sel_groups) == 1, (
|
|
183
|
+
f"Expected 1 selected group, got {len(sel_groups)}"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Plot results - this should create or reuse a "Results" group
|
|
187
|
+
panel.plot_results(kind="one_curve_per_title", xaxis="indices", yaxis="Δx")
|
|
188
|
+
|
|
189
|
+
# Verify a new group was created
|
|
190
|
+
groups_after = panel.objmodel.get_groups()
|
|
191
|
+
assert len(groups_after) == groups_before + 1, (
|
|
192
|
+
f"Expected {groups_before + 1} groups, got {len(groups_after)}"
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
# Check that the new group is named "Results" (or its translation)
|
|
196
|
+
expected_title = _("Results")
|
|
197
|
+
result_group = groups_after[-1] # Last group should be Results
|
|
198
|
+
assert result_group.title == expected_title, (
|
|
199
|
+
f"Expected last group to be '{expected_title}', "
|
|
200
|
+
f"got '{result_group.title}'"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# Check that the Results group contains at least one result signal
|
|
204
|
+
assert len(result_group) > 0, (
|
|
205
|
+
"Results group should contain at least one result signal"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
# Verify that the result signal title includes source object short IDs
|
|
209
|
+
result_signal = list(result_group)[0]
|
|
210
|
+
# Should contain all three source signal IDs: s001, s002, s003
|
|
211
|
+
# (s000 is the default group, so signals start at s001)
|
|
212
|
+
assert "(s001, s002, s003)" in result_signal.title, (
|
|
213
|
+
f"Result signal title should include source IDs (s001, s002, s003), "
|
|
214
|
+
f"got '{result_signal.title}'"
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# Test that the group is reused: create another group and plot results
|
|
218
|
+
test_group_2 = panel.add_group("Test Group 2")
|
|
219
|
+
test_group_2_id = get_uuid(test_group_2)
|
|
220
|
+
for i, (sig, _fwhm) in enumerate(
|
|
221
|
+
iterate_noisy_signals(2, a=10.0, sigma=0.01)
|
|
222
|
+
):
|
|
223
|
+
sig.title = f"Signal2_{i + 1}"
|
|
224
|
+
panel.add_object(sig, group_id=test_group_2_id)
|
|
225
|
+
panel.processor.run_feature("fwhm", sigima.params.FWHMParam())
|
|
226
|
+
|
|
227
|
+
# Select the second group and plot results again
|
|
228
|
+
panel.objview.select_groups([3])
|
|
229
|
+
|
|
230
|
+
# Plot results again
|
|
231
|
+
num_results_before = len(result_group)
|
|
232
|
+
panel.plot_results(kind="one_curve_per_title", xaxis="indices", yaxis="Δx")
|
|
233
|
+
|
|
234
|
+
# Verify no new group was created (reused existing Results group)
|
|
235
|
+
groups_final = panel.objmodel.get_groups()
|
|
236
|
+
assert len(groups_final) == len(groups_after), (
|
|
237
|
+
"Results group should be reused, no new group created"
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# Verify more results were added to the existing Results group
|
|
241
|
+
assert len(result_group) > num_results_before, (
|
|
242
|
+
"More results should be added to the existing Results group"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# Test with many objects (more than 3) to verify "..." is used
|
|
246
|
+
test_group_3 = panel.add_group("Test Group 3")
|
|
247
|
+
test_group_3_id = get_uuid(test_group_3)
|
|
248
|
+
for i, (sig, _fwhm) in enumerate(
|
|
249
|
+
iterate_noisy_signals(5, a=10.0, sigma=0.01)
|
|
250
|
+
):
|
|
251
|
+
sig.title = f"Signal3_{i + 1}"
|
|
252
|
+
panel.add_object(sig, group_id=test_group_3_id)
|
|
253
|
+
panel.processor.run_feature("fwhm", sigima.params.FWHMParam())
|
|
254
|
+
|
|
255
|
+
# Select the third group
|
|
256
|
+
panel.objview.select_groups([4])
|
|
257
|
+
|
|
258
|
+
# Plot results
|
|
259
|
+
num_results_before = len(result_group)
|
|
260
|
+
panel.plot_results(kind="one_curve_per_title", xaxis="indices", yaxis="Δx")
|
|
261
|
+
|
|
262
|
+
# Verify the result signal title uses "..." for many objects
|
|
263
|
+
new_results = list(result_group)[num_results_before:]
|
|
264
|
+
assert len(new_results) > 0, "Should have new results"
|
|
265
|
+
result_signal_many = new_results[0]
|
|
266
|
+
# With 5 source signals, should show first 2 IDs, "...", then last ID
|
|
267
|
+
# Format: "fwhm (s..., s..., ..., s...): ..."
|
|
268
|
+
assert ", ..., " in result_signal_many.title, (
|
|
269
|
+
f"Result signal title should use '...' before last ID, "
|
|
270
|
+
f"got '{result_signal_many.title}'"
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
test_plot_results_signals_one_curve_per_title()
|
|
276
|
+
test_plot_results_images_one_curve_per_object()
|
|
277
|
+
test_plot_results_images_with_rois()
|
|
278
|
+
test_plot_results_with_group_selection()
|