datalab-platform 0.0.1.dev0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datalab/__init__.py +35 -2
- datalab/adapters_metadata/__init__.py +31 -0
- datalab/adapters_metadata/base_adapter.py +316 -0
- datalab/adapters_metadata/common.py +422 -0
- datalab/adapters_metadata/geometry_adapter.py +98 -0
- datalab/adapters_metadata/table_adapter.py +84 -0
- datalab/adapters_plotpy/__init__.py +54 -0
- datalab/adapters_plotpy/annotations.py +124 -0
- datalab/adapters_plotpy/base.py +110 -0
- datalab/adapters_plotpy/converters.py +86 -0
- datalab/adapters_plotpy/factories.py +80 -0
- datalab/adapters_plotpy/objects/__init__.py +0 -0
- datalab/adapters_plotpy/objects/base.py +197 -0
- datalab/adapters_plotpy/objects/image.py +157 -0
- datalab/adapters_plotpy/objects/scalar.py +565 -0
- datalab/adapters_plotpy/objects/signal.py +264 -0
- datalab/adapters_plotpy/roi/__init__.py +0 -0
- datalab/adapters_plotpy/roi/base.py +146 -0
- datalab/adapters_plotpy/roi/factory.py +93 -0
- datalab/adapters_plotpy/roi/image.py +207 -0
- datalab/adapters_plotpy/roi/signal.py +72 -0
- datalab/app.py +98 -0
- datalab/config.py +817 -0
- datalab/control/__init__.py +0 -0
- datalab/control/baseproxy.py +776 -0
- datalab/control/proxy.py +343 -0
- datalab/control/remote.py +1005 -0
- datalab/data/doc/DataLab_en.pdf +0 -0
- datalab/data/doc/DataLab_fr.pdf +0 -0
- datalab/data/icons/analysis/delete_results.svg +109 -0
- datalab/data/icons/analysis/fw1e2.svg +156 -0
- datalab/data/icons/analysis/fwhm.svg +156 -0
- datalab/data/icons/analysis/histogram.svg +49 -0
- datalab/data/icons/analysis/peak_detect.svg +160 -0
- datalab/data/icons/analysis/plot_results.svg +151 -0
- datalab/data/icons/analysis/show_results.svg +83 -0
- datalab/data/icons/analysis/stats.svg +49 -0
- datalab/data/icons/analysis.svg +120 -0
- datalab/data/icons/apply.svg +3 -0
- datalab/data/icons/check_all.svg +15 -0
- datalab/data/icons/collapse.svg +44 -0
- datalab/data/icons/collapse_selection.svg +63 -0
- datalab/data/icons/console.svg +101 -0
- datalab/data/icons/create/1d-normal.svg +8 -0
- datalab/data/icons/create/1d-poisson.svg +9 -0
- datalab/data/icons/create/1d-uniform.svg +8 -0
- datalab/data/icons/create/1d-zero.svg +57 -0
- datalab/data/icons/create/2d-gaussian.svg +56 -0
- datalab/data/icons/create/2d-normal.svg +38 -0
- datalab/data/icons/create/2d-poisson.svg +38 -0
- datalab/data/icons/create/2d-ramp.svg +90 -0
- datalab/data/icons/create/2d-sinc.svg +62 -0
- datalab/data/icons/create/2d-uniform.svg +38 -0
- datalab/data/icons/create/2d-zero.svg +13 -0
- datalab/data/icons/create/checkerboard.svg +39 -0
- datalab/data/icons/create/cosine.svg +12 -0
- datalab/data/icons/create/exponential.svg +55 -0
- datalab/data/icons/create/gaussian.svg +12 -0
- datalab/data/icons/create/grating.svg +29 -0
- datalab/data/icons/create/linear_chirp.svg +7 -0
- datalab/data/icons/create/logistic.svg +7 -0
- datalab/data/icons/create/lorentzian.svg +12 -0
- datalab/data/icons/create/planck.svg +12 -0
- datalab/data/icons/create/polynomial.svg +7 -0
- datalab/data/icons/create/pulse.svg +12 -0
- datalab/data/icons/create/ring.svg +18 -0
- datalab/data/icons/create/sawtooth.svg +7 -0
- datalab/data/icons/create/siemens.svg +35 -0
- datalab/data/icons/create/sinc.svg +12 -0
- datalab/data/icons/create/sine.svg +7 -0
- datalab/data/icons/create/square.svg +7 -0
- datalab/data/icons/create/square_pulse.svg +7 -0
- datalab/data/icons/create/step.svg +7 -0
- datalab/data/icons/create/step_pulse.svg +12 -0
- datalab/data/icons/create/triangle.svg +7 -0
- datalab/data/icons/create/voigt.svg +12 -0
- datalab/data/icons/edit/annotations.svg +72 -0
- datalab/data/icons/edit/annotations_copy.svg +114 -0
- datalab/data/icons/edit/annotations_delete.svg +83 -0
- datalab/data/icons/edit/annotations_edit.svg +98 -0
- datalab/data/icons/edit/annotations_export.svg +85 -0
- datalab/data/icons/edit/annotations_import.svg +85 -0
- datalab/data/icons/edit/annotations_paste.svg +100 -0
- datalab/data/icons/edit/copy_titles.svg +109 -0
- datalab/data/icons/edit/delete.svg +84 -0
- datalab/data/icons/edit/delete_all.svg +214 -0
- datalab/data/icons/edit/duplicate.svg +64 -0
- datalab/data/icons/edit/goto_source.svg +60 -0
- datalab/data/icons/edit/metadata.svg +60 -0
- datalab/data/icons/edit/metadata_add.svg +80 -0
- datalab/data/icons/edit/metadata_copy.svg +96 -0
- datalab/data/icons/edit/metadata_delete.svg +62 -0
- datalab/data/icons/edit/metadata_export.svg +68 -0
- datalab/data/icons/edit/metadata_import.svg +68 -0
- datalab/data/icons/edit/metadata_paste.svg +79 -0
- datalab/data/icons/edit/move_down.svg +55 -0
- datalab/data/icons/edit/move_up.svg +54 -0
- datalab/data/icons/edit/new_group.svg +76 -0
- datalab/data/icons/edit/recompute.svg +60 -0
- datalab/data/icons/edit/rename.svg +49 -0
- datalab/data/icons/edit.svg +16 -0
- datalab/data/icons/expand.svg +44 -0
- datalab/data/icons/expand_selection.svg +63 -0
- datalab/data/icons/fit/cdf_fit.svg +56 -0
- datalab/data/icons/fit/exponential_fit.svg +55 -0
- datalab/data/icons/fit/gaussian_fit.svg +62 -0
- datalab/data/icons/fit/interactive_fit.svg +101 -0
- datalab/data/icons/fit/linear_fit.svg +57 -0
- datalab/data/icons/fit/lorentzian_fit.svg +209 -0
- datalab/data/icons/fit/multigaussian_fit.svg +85 -0
- datalab/data/icons/fit/multilorentzian_fit.svg +85 -0
- datalab/data/icons/fit/piecewiseexponential_fit.svg +209 -0
- datalab/data/icons/fit/planckian_fit.svg +62 -0
- datalab/data/icons/fit/polynomial_fit.svg +59 -0
- datalab/data/icons/fit/sigmoid_fit.svg +56 -0
- datalab/data/icons/fit/sinusoidal_fit.svg +72 -0
- datalab/data/icons/fit/twohalfgaussian_fit.svg +63 -0
- datalab/data/icons/fit/voigt_fit.svg +57 -0
- datalab/data/icons/group.svg +56 -0
- datalab/data/icons/h5/h5array.svg +59 -0
- datalab/data/icons/h5/h5attrs.svg +75 -0
- datalab/data/icons/h5/h5browser.svg +133 -0
- datalab/data/icons/h5/h5file.svg +69 -0
- datalab/data/icons/h5/h5group.svg +49 -0
- datalab/data/icons/h5/h5scalar.svg +1 -0
- datalab/data/icons/help_pdf.svg +46 -0
- datalab/data/icons/history.svg +7 -0
- datalab/data/icons/image.svg +135 -0
- datalab/data/icons/io/fileopen_directory.svg +60 -0
- datalab/data/icons/io/fileopen_h5.svg +84 -0
- datalab/data/icons/io/fileopen_ima.svg +187 -0
- datalab/data/icons/io/fileopen_py.svg +123 -0
- datalab/data/icons/io/fileopen_sig.svg +138 -0
- datalab/data/icons/io/filesave_h5.svg +97 -0
- datalab/data/icons/io/filesave_ima.svg +200 -0
- datalab/data/icons/io/filesave_py.svg +136 -0
- datalab/data/icons/io/filesave_sig.svg +151 -0
- datalab/data/icons/io/import_text.svg +144 -0
- datalab/data/icons/io/save_to_directory.svg +134 -0
- datalab/data/icons/io.svg +84 -0
- datalab/data/icons/libre-camera-flash-off.svg +1 -0
- datalab/data/icons/libre-camera-flash-on.svg +1 -0
- datalab/data/icons/libre-gui-about.svg +1 -0
- datalab/data/icons/libre-gui-action-delete.svg +1 -0
- datalab/data/icons/libre-gui-add.svg +1 -0
- datalab/data/icons/libre-gui-arrow-down.svg +1 -0
- datalab/data/icons/libre-gui-arrow-left.svg +1 -0
- datalab/data/icons/libre-gui-arrow-right.svg +1 -0
- datalab/data/icons/libre-gui-arrow-up.svg +1 -0
- datalab/data/icons/libre-gui-close.svg +40 -0
- datalab/data/icons/libre-gui-cogs.svg +1 -0
- datalab/data/icons/libre-gui-globe.svg +1 -0
- datalab/data/icons/libre-gui-help.svg +1 -0
- datalab/data/icons/libre-gui-link.svg +1 -0
- datalab/data/icons/libre-gui-menu.svg +1 -0
- datalab/data/icons/libre-gui-pencil.svg +1 -0
- datalab/data/icons/libre-gui-plugin.svg +1 -0
- datalab/data/icons/libre-gui-questions.svg +1 -0
- datalab/data/icons/libre-gui-settings.svg +1 -0
- datalab/data/icons/libre-gui-unlink.svg +1 -0
- datalab/data/icons/libre-tech-ram.svg +1 -0
- datalab/data/icons/libre-toolbox.svg +1 -0
- datalab/data/icons/logs.svg +1 -0
- datalab/data/icons/markers.svg +74 -0
- datalab/data/icons/menu.svg +13 -0
- datalab/data/icons/new_ima.svg +148 -0
- datalab/data/icons/new_sig.svg +123 -0
- datalab/data/icons/operations/abs.svg +116 -0
- datalab/data/icons/operations/arithmetic.svg +123 -0
- datalab/data/icons/operations/average.svg +124 -0
- datalab/data/icons/operations/complex_from_magnitude_phase.svg +116 -0
- datalab/data/icons/operations/complex_from_real_imag.svg +124 -0
- datalab/data/icons/operations/constant.svg +116 -0
- datalab/data/icons/operations/constant_add.svg +109 -0
- datalab/data/icons/operations/constant_divide.svg +109 -0
- datalab/data/icons/operations/constant_multiply.svg +109 -0
- datalab/data/icons/operations/constant_subtract.svg +109 -0
- datalab/data/icons/operations/convert_dtype.svg +117 -0
- datalab/data/icons/operations/convolution.svg +46 -0
- datalab/data/icons/operations/deconvolution.svg +57 -0
- datalab/data/icons/operations/derivative.svg +127 -0
- datalab/data/icons/operations/difference.svg +52 -0
- datalab/data/icons/operations/division.svg +139 -0
- datalab/data/icons/operations/exp.svg +116 -0
- datalab/data/icons/operations/flip_horizontally.svg +69 -0
- datalab/data/icons/operations/flip_vertically.svg +74 -0
- datalab/data/icons/operations/im.svg +124 -0
- datalab/data/icons/operations/integral.svg +50 -0
- datalab/data/icons/operations/inverse.svg +143 -0
- datalab/data/icons/operations/log10.svg +109 -0
- datalab/data/icons/operations/phase.svg +116 -0
- datalab/data/icons/operations/power.svg +118 -0
- datalab/data/icons/operations/product.svg +124 -0
- datalab/data/icons/operations/profile.svg +379 -0
- datalab/data/icons/operations/profile_average.svg +399 -0
- datalab/data/icons/operations/profile_radial.svg +261 -0
- datalab/data/icons/operations/profile_segment.svg +262 -0
- datalab/data/icons/operations/quadratic_difference.svg +84 -0
- datalab/data/icons/operations/re.svg +124 -0
- datalab/data/icons/operations/rotate_left.svg +72 -0
- datalab/data/icons/operations/rotate_right.svg +72 -0
- datalab/data/icons/operations/signals_to_image.svg +314 -0
- datalab/data/icons/operations/sqrt.svg +110 -0
- datalab/data/icons/operations/std.svg +124 -0
- datalab/data/icons/operations/sum.svg +102 -0
- datalab/data/icons/play_demo.svg +9 -0
- datalab/data/icons/processing/axis_transform.svg +62 -0
- datalab/data/icons/processing/bandpass.svg +79 -0
- datalab/data/icons/processing/bandstop.svg +71 -0
- datalab/data/icons/processing/binning.svg +126 -0
- datalab/data/icons/processing/clip.svg +119 -0
- datalab/data/icons/processing/detrending.svg +173 -0
- datalab/data/icons/processing/distribute_on_grid.svg +769 -0
- datalab/data/icons/processing/edge_detection.svg +46 -0
- datalab/data/icons/processing/erase.svg +1 -0
- datalab/data/icons/processing/exposure.svg +143 -0
- datalab/data/icons/processing/fourier.svg +104 -0
- datalab/data/icons/processing/highpass.svg +59 -0
- datalab/data/icons/processing/interpolation.svg +71 -0
- datalab/data/icons/processing/level_adjustment.svg +70 -0
- datalab/data/icons/processing/lowpass.svg +60 -0
- datalab/data/icons/processing/morphology.svg +49 -0
- datalab/data/icons/processing/noise_addition.svg +114 -0
- datalab/data/icons/processing/noise_reduction.svg +38 -0
- datalab/data/icons/processing/normalize.svg +84 -0
- datalab/data/icons/processing/offset_correction.svg +131 -0
- datalab/data/icons/processing/resampling1d.svg +101 -0
- datalab/data/icons/processing/resampling2d.svg +240 -0
- datalab/data/icons/processing/reset_positions.svg +185 -0
- datalab/data/icons/processing/resize.svg +9 -0
- datalab/data/icons/processing/reverse_signal_x.svg +171 -0
- datalab/data/icons/processing/stability.svg +11 -0
- datalab/data/icons/processing/swap_x_y.svg +65 -0
- datalab/data/icons/processing/thresholding.svg +63 -0
- datalab/data/icons/processing/windowing.svg +45 -0
- datalab/data/icons/properties.svg +26 -0
- datalab/data/icons/reset.svg +9 -0
- datalab/data/icons/restore.svg +40 -0
- datalab/data/icons/roi/roi.svg +76 -0
- datalab/data/icons/roi/roi_coordinate.svg +78 -0
- datalab/data/icons/roi/roi_copy.svg +112 -0
- datalab/data/icons/roi/roi_delete.svg +81 -0
- datalab/data/icons/roi/roi_export.svg +87 -0
- datalab/data/icons/roi/roi_graphical.svg +78 -0
- datalab/data/icons/roi/roi_grid.svg +67 -0
- datalab/data/icons/roi/roi_ima.svg +188 -0
- datalab/data/icons/roi/roi_import.svg +87 -0
- datalab/data/icons/roi/roi_new.svg +81 -0
- datalab/data/icons/roi/roi_new_circle.svg +95 -0
- datalab/data/icons/roi/roi_new_polygon.svg +110 -0
- datalab/data/icons/roi/roi_new_rectangle.svg +70 -0
- datalab/data/icons/roi/roi_paste.svg +98 -0
- datalab/data/icons/roi/roi_sig.svg +124 -0
- datalab/data/icons/shapes.svg +134 -0
- datalab/data/icons/signal.svg +103 -0
- datalab/data/icons/table.svg +85 -0
- datalab/data/icons/table_unavailable.svg +102 -0
- datalab/data/icons/to_signal.svg +124 -0
- datalab/data/icons/tour/next.svg +44 -0
- datalab/data/icons/tour/previous.svg +44 -0
- datalab/data/icons/tour/rewind.svg +51 -0
- datalab/data/icons/tour/stop.svg +47 -0
- datalab/data/icons/tour/tour.svg +16 -0
- datalab/data/icons/uncheck_all.svg +78 -0
- datalab/data/icons/view/curve_antialiasing.svg +50 -0
- datalab/data/icons/view/new_window.svg +98 -0
- datalab/data/icons/view/refresh-auto.svg +57 -0
- datalab/data/icons/view/refresh-manual.svg +51 -0
- datalab/data/icons/view/reset_curve_styles.svg +96 -0
- datalab/data/icons/view/show_first.svg +55 -0
- datalab/data/icons/view/show_titles.svg +46 -0
- datalab/data/icons/visualization.svg +51 -0
- datalab/data/logo/DataLab-Banner-150.png +0 -0
- datalab/data/logo/DataLab-Banner-200.png +0 -0
- datalab/data/logo/DataLab-Banner2-100.png +0 -0
- datalab/data/logo/DataLab-Splash.png +0 -0
- datalab/data/logo/DataLab-watermark.png +0 -0
- datalab/data/logo/DataLab.svg +83 -0
- datalab/data/tests/reordering_test.h5 +0 -0
- datalab/data/tutorials/fabry_perot/fabry-perot1.jpg +0 -0
- datalab/data/tutorials/fabry_perot/fabry-perot2.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_13.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_18.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_23.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_30.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_35.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_40.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_45.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_50.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_55.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_60.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_65.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_70.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_75.jpg +0 -0
- datalab/data/tutorials/laser_beam/TEM00_z_80.jpg +0 -0
- datalab/env.py +542 -0
- datalab/gui/__init__.py +89 -0
- datalab/gui/actionhandler.py +1701 -0
- datalab/gui/docks.py +473 -0
- datalab/gui/h5io.py +150 -0
- datalab/gui/macroeditor.py +310 -0
- datalab/gui/main.py +2081 -0
- datalab/gui/newobject.py +217 -0
- datalab/gui/objectview.py +766 -0
- datalab/gui/panel/__init__.py +48 -0
- datalab/gui/panel/base.py +3254 -0
- datalab/gui/panel/image.py +157 -0
- datalab/gui/panel/macro.py +607 -0
- datalab/gui/panel/signal.py +164 -0
- datalab/gui/plothandler.py +800 -0
- datalab/gui/processor/__init__.py +84 -0
- datalab/gui/processor/base.py +2456 -0
- datalab/gui/processor/catcher.py +75 -0
- datalab/gui/processor/image.py +1214 -0
- datalab/gui/processor/signal.py +755 -0
- datalab/gui/profiledialog.py +333 -0
- datalab/gui/roieditor.py +633 -0
- datalab/gui/roigrideditor.py +208 -0
- datalab/gui/settings.py +612 -0
- datalab/gui/tour.py +908 -0
- datalab/h5/__init__.py +12 -0
- datalab/h5/common.py +314 -0
- datalab/h5/generic.py +580 -0
- datalab/h5/native.py +39 -0
- datalab/h5/utils.py +95 -0
- datalab/objectmodel.py +640 -0
- datalab/plugins/_readme_.txt +9 -0
- datalab/plugins/datalab_imageformats.py +175 -0
- datalab/plugins/datalab_testdata.py +190 -0
- datalab/plugins.py +355 -0
- datalab/tests/__init__.py +199 -0
- datalab/tests/backbone/__init__.py +1 -0
- datalab/tests/backbone/config_unit_test.py +170 -0
- datalab/tests/backbone/config_versioning_unit_test.py +34 -0
- datalab/tests/backbone/dictlistserial_app_test.py +38 -0
- datalab/tests/backbone/errorcatcher_unit_test.py +69 -0
- datalab/tests/backbone/errormsgbox_unit_test.py +50 -0
- datalab/tests/backbone/execenv_unit.py +262 -0
- datalab/tests/backbone/loadtest_gdi.py +147 -0
- datalab/tests/backbone/long_callback.py +96 -0
- datalab/tests/backbone/main_app_test.py +137 -0
- datalab/tests/backbone/memory_leak.py +43 -0
- datalab/tests/backbone/procisolation1_unit.py +128 -0
- datalab/tests/backbone/procisolation2_unit.py +171 -0
- datalab/tests/backbone/procisolation_unit_test.py +22 -0
- datalab/tests/backbone/profiling_app.py +27 -0
- datalab/tests/backbone/strings_unit_test.py +65 -0
- datalab/tests/backbone/title_formatting_unit_test.py +82 -0
- datalab/tests/conftest.py +131 -0
- datalab/tests/features/__init__.py +1 -0
- datalab/tests/features/applauncher/__init__.py +1 -0
- datalab/tests/features/applauncher/launcher1_app_test.py +28 -0
- datalab/tests/features/applauncher/launcher2_app_test.py +30 -0
- datalab/tests/features/common/__init__.py +1 -0
- datalab/tests/features/common/add_metadata_app_test.py +134 -0
- datalab/tests/features/common/add_metadata_unit_test.py +267 -0
- datalab/tests/features/common/annotations_management_unit_test.py +152 -0
- datalab/tests/features/common/auto_analysis_recompute_unit_test.py +240 -0
- datalab/tests/features/common/createobject_unit_test.py +50 -0
- datalab/tests/features/common/geometry_results_app_test.py +135 -0
- datalab/tests/features/common/interactive_processing_test.py +1109 -0
- datalab/tests/features/common/io_app_test.py +75 -0
- datalab/tests/features/common/large_results_app_test.py +187 -0
- datalab/tests/features/common/metadata_all_patterns_test.py +103 -0
- datalab/tests/features/common/metadata_app_test.py +139 -0
- datalab/tests/features/common/metadata_io_unit_test.py +60 -0
- datalab/tests/features/common/misc_app_test.py +236 -0
- datalab/tests/features/common/multiple_geometry_results_unit_test.py +122 -0
- datalab/tests/features/common/multiple_table_results_unit_test.py +64 -0
- datalab/tests/features/common/operation_modes_app_test.py +392 -0
- datalab/tests/features/common/plot_results_app_test.py +278 -0
- datalab/tests/features/common/reorder_app_test.py +75 -0
- datalab/tests/features/common/result_deletion_unit_test.py +96 -0
- datalab/tests/features/common/result_merged_label_unit_test.py +154 -0
- datalab/tests/features/common/result_shape_settings_unit_test.py +223 -0
- datalab/tests/features/common/roi_plotitem_unit_test.py +64 -0
- datalab/tests/features/common/roieditor_unit_test.py +102 -0
- datalab/tests/features/common/save_to_dir_app_test.py +163 -0
- datalab/tests/features/common/save_to_dir_unit_test.py +474 -0
- datalab/tests/features/common/stat_app_test.py +40 -0
- datalab/tests/features/common/stats_tools_unit_test.py +77 -0
- datalab/tests/features/common/table_results_app_test.py +52 -0
- datalab/tests/features/common/textimport_unit_test.py +131 -0
- datalab/tests/features/common/uuid_preservation_test.py +281 -0
- datalab/tests/features/common/worker_unit_test.py +402 -0
- datalab/tests/features/control/__init__.py +1 -0
- datalab/tests/features/control/connect_dialog.py +28 -0
- datalab/tests/features/control/embedded1_unit_test.py +304 -0
- datalab/tests/features/control/embedded2_unit_test.py +52 -0
- datalab/tests/features/control/remoteclient_app_test.py +219 -0
- datalab/tests/features/control/remoteclient_unit.py +75 -0
- datalab/tests/features/control/simpleclient_unit_test.py +321 -0
- datalab/tests/features/hdf5/__init__.py +1 -0
- datalab/tests/features/hdf5/h5browser1_unit_test.py +31 -0
- datalab/tests/features/hdf5/h5browser2_unit.py +55 -0
- datalab/tests/features/hdf5/h5browser_app_test.py +77 -0
- datalab/tests/features/hdf5/h5import_app_test.py +25 -0
- datalab/tests/features/hdf5/h5importer_app_test.py +34 -0
- datalab/tests/features/image/__init__.py +1 -0
- datalab/tests/features/image/annotations_app_test.py +28 -0
- datalab/tests/features/image/annotations_unit_test.py +80 -0
- datalab/tests/features/image/average_app_test.py +46 -0
- datalab/tests/features/image/background_dialog_test.py +70 -0
- datalab/tests/features/image/blobs_app_test.py +50 -0
- datalab/tests/features/image/contour_app_test.py +42 -0
- datalab/tests/features/image/contour_fabryperot_app_test.py +51 -0
- datalab/tests/features/image/denoise_app_test.py +31 -0
- datalab/tests/features/image/distribute_on_grid_app_test.py +95 -0
- datalab/tests/features/image/edges_app_test.py +31 -0
- datalab/tests/features/image/erase_app_test.py +21 -0
- datalab/tests/features/image/fft2d_app_test.py +27 -0
- datalab/tests/features/image/flatfield_app_test.py +40 -0
- datalab/tests/features/image/geometry_transform_unit_test.py +396 -0
- datalab/tests/features/image/imagetools_app_test.py +51 -0
- datalab/tests/features/image/imagetools_unit_test.py +27 -0
- datalab/tests/features/image/load_app_test.py +73 -0
- datalab/tests/features/image/morph_app_test.py +32 -0
- datalab/tests/features/image/offsetcorrection_app_test.py +30 -0
- datalab/tests/features/image/peak2d_app_test.py +53 -0
- datalab/tests/features/image/profile_app_test.py +73 -0
- datalab/tests/features/image/profile_dialog_test.py +56 -0
- datalab/tests/features/image/roi_app_test.py +98 -0
- datalab/tests/features/image/roi_circ_app_test.py +62 -0
- datalab/tests/features/image/roi_manipulation_app_test.py +268 -0
- datalab/tests/features/image/roigrid_unit_test.py +60 -0
- datalab/tests/features/image/side_by_side_app_test.py +52 -0
- datalab/tests/features/macro/__init__.py +1 -0
- datalab/tests/features/macro/macro_app_test.py +28 -0
- datalab/tests/features/macro/macroeditor_unit_test.py +102 -0
- datalab/tests/features/signal/__init__.py +1 -0
- datalab/tests/features/signal/baseline_dialog_test.py +53 -0
- datalab/tests/features/signal/deltax_dialog_unit_test.py +34 -0
- datalab/tests/features/signal/fft1d_app_test.py +26 -0
- datalab/tests/features/signal/filter_app_test.py +44 -0
- datalab/tests/features/signal/fitdialog_unit_test.py +50 -0
- datalab/tests/features/signal/interpolation_app_test.py +110 -0
- datalab/tests/features/signal/loadbigsignal_app_test.py +80 -0
- datalab/tests/features/signal/multiple_rois_unit_test.py +132 -0
- datalab/tests/features/signal/pulse_features_app_test.py +118 -0
- datalab/tests/features/signal/pulse_features_roi_app_test.py +55 -0
- datalab/tests/features/signal/roi_app_test.py +78 -0
- datalab/tests/features/signal/roi_manipulation_app_test.py +261 -0
- datalab/tests/features/signal/select_xy_cursor_unit_test.py +46 -0
- datalab/tests/features/signal/signalpeakdetection_dialog_test.py +33 -0
- datalab/tests/features/signal/signals_to_image_app_test.py +98 -0
- datalab/tests/features/signal/xarray_compat_app_test.py +128 -0
- datalab/tests/features/tour_unit_test.py +22 -0
- datalab/tests/features/utilities/__init__.py +1 -0
- datalab/tests/features/utilities/installconf_unit_test.py +21 -0
- datalab/tests/features/utilities/logview_app_test.py +21 -0
- datalab/tests/features/utilities/logview_error.py +24 -0
- datalab/tests/features/utilities/logview_unit_test.py +21 -0
- datalab/tests/features/utilities/memstatus_app_test.py +42 -0
- datalab/tests/features/utilities/settings_unit_test.py +88 -0
- datalab/tests/scenarios/__init__.py +1 -0
- datalab/tests/scenarios/beautiful_app.py +121 -0
- datalab/tests/scenarios/common.py +463 -0
- datalab/tests/scenarios/demo.py +212 -0
- datalab/tests/scenarios/example_app_test.py +47 -0
- datalab/tests/scenarios/scenario_h5_app_test.py +75 -0
- datalab/tests/scenarios/scenario_ima1_app_test.py +34 -0
- datalab/tests/scenarios/scenario_ima2_app_test.py +34 -0
- datalab/tests/scenarios/scenario_mac_app_test.py +58 -0
- datalab/tests/scenarios/scenario_sig1_app_test.py +36 -0
- datalab/tests/scenarios/scenario_sig2_app_test.py +35 -0
- datalab/utils/__init__.py +1 -0
- datalab/utils/conf.py +304 -0
- datalab/utils/dephash.py +105 -0
- datalab/utils/qthelpers.py +633 -0
- datalab/utils/strings.py +34 -0
- datalab/utils/tests.py +0 -0
- datalab/widgets/__init__.py +1 -0
- datalab/widgets/connection.py +138 -0
- datalab/widgets/filedialog.py +91 -0
- datalab/widgets/fileviewer.py +84 -0
- datalab/widgets/fitdialog.py +788 -0
- datalab/widgets/h5browser.py +1048 -0
- datalab/widgets/imagebackground.py +111 -0
- datalab/widgets/instconfviewer.py +175 -0
- datalab/widgets/logviewer.py +80 -0
- datalab/widgets/signalbaseline.py +90 -0
- datalab/widgets/signalcursor.py +208 -0
- datalab/widgets/signaldeltax.py +151 -0
- datalab/widgets/signalpeak.py +199 -0
- datalab/widgets/status.py +249 -0
- datalab/widgets/textimport.py +786 -0
- datalab/widgets/warningerror.py +223 -0
- datalab/widgets/wizard.py +286 -0
- datalab_platform-1.0.0.dist-info/METADATA +121 -0
- datalab_platform-1.0.0.dist-info/RECORD +494 -0
- datalab_platform-0.0.1.dev0.dist-info/METADATA +0 -67
- datalab_platform-0.0.1.dev0.dist-info/RECORD +0 -7
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/WHEEL +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/entry_points.txt +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
GUI dialog for analyzing signals and calculating full width at Y.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import warnings
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
from guidata.configtools import get_icon
|
|
16
|
+
from plotpy.builder import make
|
|
17
|
+
from plotpy.plot import PlotDialog
|
|
18
|
+
from qtpy import QtGui as QG
|
|
19
|
+
from qtpy import QtWidgets as QW
|
|
20
|
+
from sigima.tools.signal.pulse import full_width_at_y
|
|
21
|
+
|
|
22
|
+
from datalab.adapters_plotpy import CURVESTYLES, create_adapter_from_object
|
|
23
|
+
from datalab.config import _
|
|
24
|
+
from datalab.utils.qthelpers import resize_widget_to_parent
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from plotpy.items import CurveItem, Marker, XRangeSelection
|
|
28
|
+
from qtpy.QtWidgets import QWidget
|
|
29
|
+
from sigima.objects import SignalObj
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SignalDeltaXDialog(PlotDialog):
|
|
33
|
+
"""Signal Delta X dialog.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
signal: signal object
|
|
37
|
+
parent: parent widget. Defaults to None.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, signal: SignalObj, parent: QWidget | None = None) -> None:
|
|
41
|
+
self.__curve_styles = CURVESTYLES.style_generator()
|
|
42
|
+
self.__signal = signal
|
|
43
|
+
self.__coords: list[float, float, float, float] | None = None
|
|
44
|
+
self.curve: CurveItem | None = None
|
|
45
|
+
self.hcursor: Marker | None = None
|
|
46
|
+
self.delta_xrange: XRangeSelection | None = None
|
|
47
|
+
self.deltaxlineedit: QW.QLineEdit | None = None
|
|
48
|
+
self.ylineedit: QW.QLineEdit | None = None
|
|
49
|
+
title = _("Select Y value with cursor")
|
|
50
|
+
super().__init__(title=title, edit=True, parent=parent)
|
|
51
|
+
self.setObjectName("SignalCursorDialog")
|
|
52
|
+
if parent is None:
|
|
53
|
+
self.setWindowIcon(get_icon("DataLab.svg"))
|
|
54
|
+
legend = make.legend("TR")
|
|
55
|
+
self.get_plot().add_item(legend)
|
|
56
|
+
self.__setup_dialog()
|
|
57
|
+
resize_widget_to_parent(self, aspect_ratio=1.0)
|
|
58
|
+
|
|
59
|
+
def __setup_dialog(self) -> None:
|
|
60
|
+
"""Setup dialog box"""
|
|
61
|
+
apply_button = QW.QPushButton(_("Apply"))
|
|
62
|
+
apply_button.setIcon(get_icon("apply.svg"))
|
|
63
|
+
apply_button.setToolTip(_("Apply cursor position"))
|
|
64
|
+
xlabel = QW.QLabel("∆X=")
|
|
65
|
+
ylabel = QW.QLabel("Y=")
|
|
66
|
+
self.deltaxlineedit = QW.QLineEdit()
|
|
67
|
+
self.deltaxlineedit.setReadOnly(True)
|
|
68
|
+
self.deltaxlineedit.setDisabled(True)
|
|
69
|
+
self.ylineedit = QW.QLineEdit()
|
|
70
|
+
self.ylineedit.editingFinished.connect(self.ylineedit_editing_finished)
|
|
71
|
+
self.ylineedit.setValidator(QG.QDoubleValidator())
|
|
72
|
+
xygroup = QW.QGroupBox(_("Cursor position"))
|
|
73
|
+
xylayout = QW.QHBoxLayout()
|
|
74
|
+
xylayout.addWidget(xlabel)
|
|
75
|
+
xylayout.addWidget(self.deltaxlineedit)
|
|
76
|
+
xylayout.addWidget(ylabel)
|
|
77
|
+
xylayout.addWidget(self.ylineedit)
|
|
78
|
+
xylayout.addWidget(apply_button)
|
|
79
|
+
vlayout = QW.QVBoxLayout()
|
|
80
|
+
vlayout.addLayout(xylayout)
|
|
81
|
+
self.warning_label = QW.QLabel()
|
|
82
|
+
vlayout.addWidget(self.warning_label)
|
|
83
|
+
apply_button.clicked.connect(self.ylineedit_editing_finished)
|
|
84
|
+
xygroup.setLayout(vlayout)
|
|
85
|
+
self.button_layout.insertWidget(0, xygroup)
|
|
86
|
+
|
|
87
|
+
obj = self.__signal
|
|
88
|
+
with CURVESTYLES.alternative(self.__curve_styles):
|
|
89
|
+
self.curve = create_adapter_from_object(obj).make_item()
|
|
90
|
+
plot = self.get_plot()
|
|
91
|
+
plot.set_antialiasing(True)
|
|
92
|
+
|
|
93
|
+
self.delta_xrange = make.xrange(0.0, 1.0)
|
|
94
|
+
self.delta_xrange.setVisible(False)
|
|
95
|
+
self.delta_xrange.set_style("roi", "s/readonly")
|
|
96
|
+
self.delta_xrange.set_selectable(False)
|
|
97
|
+
|
|
98
|
+
plot.SIG_MARKER_CHANGED.connect(self.cursor_changed)
|
|
99
|
+
self.hcursor = make.hcursor(np.mean(obj.y), "Y = %g")
|
|
100
|
+
for item in (self.curve, self.delta_xrange, self.hcursor):
|
|
101
|
+
plot.add_item(item)
|
|
102
|
+
plot.replot()
|
|
103
|
+
plot.set_active_item(self.hcursor)
|
|
104
|
+
self.cursor_changed(self.hcursor)
|
|
105
|
+
|
|
106
|
+
def cursor_changed(self, item: Marker) -> None:
|
|
107
|
+
"""Cursor changed"""
|
|
108
|
+
sig = self.__signal
|
|
109
|
+
_x, y = item.get_pos()
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
with warnings.catch_warnings(record=True) as w:
|
|
113
|
+
self.__coords = full_width_at_y(sig.x, sig.y, y)
|
|
114
|
+
if np.nan in self.__coords:
|
|
115
|
+
raise ValueError("Invalid coordinates")
|
|
116
|
+
delta_str = f"{self.__coords[2] - self.__coords[0]:g}"
|
|
117
|
+
ok = True
|
|
118
|
+
if len(w) > 0:
|
|
119
|
+
self.warning_label.setText("⚠️ " + str(w[-1].message))
|
|
120
|
+
else:
|
|
121
|
+
self.warning_label.setText("")
|
|
122
|
+
self.delta_xrange.setVisible(True)
|
|
123
|
+
self.delta_xrange.set_range(self.__coords[0], self.__coords[2])
|
|
124
|
+
except ValueError:
|
|
125
|
+
delta_str = ""
|
|
126
|
+
ok = False
|
|
127
|
+
self.delta_xrange.setVisible(False)
|
|
128
|
+
|
|
129
|
+
self.button_box.button(QW.QDialogButtonBox.Ok).setEnabled(ok)
|
|
130
|
+
self.deltaxlineedit.setText(delta_str)
|
|
131
|
+
self.ylineedit.setText(f"{y:g}" if y is not None else "")
|
|
132
|
+
|
|
133
|
+
def ylineedit_editing_finished(self) -> None:
|
|
134
|
+
"""Y line edit editing finished"""
|
|
135
|
+
try:
|
|
136
|
+
y = float(self.ylineedit.text())
|
|
137
|
+
x, _y = self.hcursor.get_pos()
|
|
138
|
+
self.hcursor.set_pos(x, y)
|
|
139
|
+
except ValueError:
|
|
140
|
+
pass
|
|
141
|
+
plot = self.get_plot()
|
|
142
|
+
plot.replot()
|
|
143
|
+
|
|
144
|
+
def get_coords(self) -> tuple[float, float, float, float]:
|
|
145
|
+
"""Return coordinates of segment associated to the width at Y"""
|
|
146
|
+
return self.__coords
|
|
147
|
+
|
|
148
|
+
def get_y_value(self) -> float:
|
|
149
|
+
"""Get cursor y value"""
|
|
150
|
+
_x, y = self.hcursor.get_pos()
|
|
151
|
+
return y
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""Signal peak detection feature"""
|
|
4
|
+
|
|
5
|
+
# pylint: disable=invalid-name # Allows short reference names like x, y, ...
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
from guidata.configtools import get_icon
|
|
13
|
+
from plotpy.builder import make
|
|
14
|
+
from plotpy.plot import PlotDialog
|
|
15
|
+
from qtpy import QtCore as QC
|
|
16
|
+
from qtpy import QtWidgets as QW
|
|
17
|
+
from sigima.tools.signal.peakdetection import peak_indices
|
|
18
|
+
|
|
19
|
+
from datalab.adapters_plotpy import CURVESTYLES, create_adapter_from_object
|
|
20
|
+
from datalab.config import _
|
|
21
|
+
from datalab.utils.qthelpers import resize_widget_to_parent
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from plotpy.items import Marker
|
|
25
|
+
from qtpy.QtWidgets import QWidget
|
|
26
|
+
from sigima.objects import SignalObj
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DistanceSlider(QW.QWidget):
|
|
30
|
+
"""Minimum distance slider
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
parent: parent widget. Defaults to None.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
TITLE = _("Minimum distance:")
|
|
37
|
+
SIG_VALUE_CHANGED = QC.Signal(int)
|
|
38
|
+
|
|
39
|
+
def __init__(self, parent: QWidget | None = None) -> None:
|
|
40
|
+
super().__init__(parent)
|
|
41
|
+
self.slider = QW.QSlider(QC.Qt.Horizontal)
|
|
42
|
+
self.label = QW.QLabel()
|
|
43
|
+
layout = QW.QHBoxLayout()
|
|
44
|
+
layout.addWidget(self.label)
|
|
45
|
+
layout.addWidget(self.slider)
|
|
46
|
+
self.setLayout(layout)
|
|
47
|
+
|
|
48
|
+
def value_changed(self, value: int) -> None:
|
|
49
|
+
"""Slider value has changed
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
value: slider value
|
|
53
|
+
"""
|
|
54
|
+
plural = "s" if value > 1 else ""
|
|
55
|
+
self.label.setText(f"{self.TITLE} {value} point{plural}")
|
|
56
|
+
self.SIG_VALUE_CHANGED.emit(value)
|
|
57
|
+
|
|
58
|
+
def setup_slider(self, value: int, maxval: int) -> None:
|
|
59
|
+
"""Setup slider
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
value: initial value
|
|
63
|
+
maxval: maximum value
|
|
64
|
+
"""
|
|
65
|
+
self.slider.setMinimum(1)
|
|
66
|
+
self.slider.setMaximum(maxval)
|
|
67
|
+
self.slider.setValue(value)
|
|
68
|
+
self.slider.setTickPosition(QW.QSlider.TicksBothSides)
|
|
69
|
+
self.value_changed(value)
|
|
70
|
+
self.slider.valueChanged.connect(self.value_changed)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class SignalPeakDetectionDialog(PlotDialog):
|
|
74
|
+
"""Signal Peak detection dialog
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
signal: signal object
|
|
78
|
+
parent: parent widget. Defaults to None.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
def __init__(self, signal: SignalObj, parent: QWidget | None = None) -> None:
|
|
82
|
+
self.__curve_styles = CURVESTYLES.style_generator()
|
|
83
|
+
self.peaks = None
|
|
84
|
+
self.peak_indices = None
|
|
85
|
+
self.in_curve = None
|
|
86
|
+
self.in_threshold = None
|
|
87
|
+
self.in_threshold_cursor = None
|
|
88
|
+
self.co_results = None
|
|
89
|
+
self.co_positions = None
|
|
90
|
+
self.co_markers = None
|
|
91
|
+
self.min_distance = None
|
|
92
|
+
self.distance_slider: DistanceSlider | None = None
|
|
93
|
+
super().__init__(title=_("Signal peak detection"), edit=True, parent=parent)
|
|
94
|
+
self.setObjectName("peakdetection")
|
|
95
|
+
if parent is None:
|
|
96
|
+
self.setWindowIcon(get_icon("DataLab.svg"))
|
|
97
|
+
legend = make.legend("TR")
|
|
98
|
+
self.get_plot().add_item(legend)
|
|
99
|
+
self.__signal = signal.copy()
|
|
100
|
+
self.__setup_dialog()
|
|
101
|
+
resize_widget_to_parent(self, parent, aspect_ratio=1.0)
|
|
102
|
+
|
|
103
|
+
def populate_plot_layout(self) -> None: # Reimplement PlotDialog method
|
|
104
|
+
"""Populate the plot layout"""
|
|
105
|
+
super().populate_plot_layout()
|
|
106
|
+
self.distance_slider = DistanceSlider(self)
|
|
107
|
+
self.add_widget(self.distance_slider, 1, 0, 1, 1)
|
|
108
|
+
|
|
109
|
+
def __setup_dialog(self) -> None:
|
|
110
|
+
"""Setup dialog box"""
|
|
111
|
+
obj = self.__signal
|
|
112
|
+
with CURVESTYLES.alternative(self.__curve_styles):
|
|
113
|
+
self.in_curve = create_adapter_from_object(obj).make_item()
|
|
114
|
+
plot = self.get_plot()
|
|
115
|
+
plot.set_antialiasing(True)
|
|
116
|
+
plot.add_item(self.in_curve)
|
|
117
|
+
self.in_threshold = 0.5 * (np.max(obj.y) - np.min(obj.y)) + np.min(obj.y)
|
|
118
|
+
cursor = make.hcursor(self.in_threshold)
|
|
119
|
+
self.in_threshold_cursor = cursor
|
|
120
|
+
plot.add_item(self.in_threshold_cursor)
|
|
121
|
+
self.co_results = make.label("", "TL", (0, 0), "TL")
|
|
122
|
+
plot.add_item(self.co_results)
|
|
123
|
+
plot.SIG_MARKER_CHANGED.connect(self.hcursor_changed)
|
|
124
|
+
self.min_distance = 1
|
|
125
|
+
self.distance_slider.setup_slider(self.min_distance, len(obj.y) // 4)
|
|
126
|
+
self.distance_slider.SIG_VALUE_CHANGED.connect(self.minimum_distance_changed)
|
|
127
|
+
self.compute_peaks()
|
|
128
|
+
# Replot, otherwise, it's not possible to set active item:
|
|
129
|
+
plot.replot()
|
|
130
|
+
plot.set_active_item(cursor)
|
|
131
|
+
|
|
132
|
+
def get_peaks(self) -> list[tuple[float, float]]:
|
|
133
|
+
"""Return peaks coordinates"""
|
|
134
|
+
return self.peaks
|
|
135
|
+
|
|
136
|
+
def get_peak_indices(self) -> list[int]:
|
|
137
|
+
"""Return peak indices"""
|
|
138
|
+
return self.peak_indices
|
|
139
|
+
|
|
140
|
+
def get_threshold(self) -> float:
|
|
141
|
+
"""Return relative threshold"""
|
|
142
|
+
y = self.__signal.y
|
|
143
|
+
return (self.in_threshold - np.min(y)) / (np.max(y) - np.min(y))
|
|
144
|
+
|
|
145
|
+
def get_min_dist(self) -> int:
|
|
146
|
+
"""Return minimum distance"""
|
|
147
|
+
return self.min_distance
|
|
148
|
+
|
|
149
|
+
def compute_peaks(self) -> None:
|
|
150
|
+
"""Compute peak detection"""
|
|
151
|
+
x, y = self.__signal.xydata
|
|
152
|
+
plot = self.get_plot()
|
|
153
|
+
self.peak_indices = peak_indices(
|
|
154
|
+
y,
|
|
155
|
+
thres=self.in_threshold,
|
|
156
|
+
min_dist=self.min_distance,
|
|
157
|
+
thres_abs=True,
|
|
158
|
+
)
|
|
159
|
+
self.peaks = [(x[index], y[index]) for index in self.peak_indices]
|
|
160
|
+
markers = [
|
|
161
|
+
make.marker(
|
|
162
|
+
pos,
|
|
163
|
+
movable=False,
|
|
164
|
+
color="orange",
|
|
165
|
+
markerstyle="|",
|
|
166
|
+
linewidth=1,
|
|
167
|
+
marker="NoSymbol",
|
|
168
|
+
linestyle="DashLine",
|
|
169
|
+
)
|
|
170
|
+
for pos in self.peaks
|
|
171
|
+
]
|
|
172
|
+
if self.co_markers is not None:
|
|
173
|
+
plot.del_items(self.co_markers)
|
|
174
|
+
self.co_markers = markers
|
|
175
|
+
for item in self.co_markers:
|
|
176
|
+
plot.add_item(item)
|
|
177
|
+
positions = [str(marker.get_pos()[0]) for marker in markers]
|
|
178
|
+
prefix = f"<b>{_('Peaks:')}</b><br>"
|
|
179
|
+
self.co_results.set_text(prefix + "<br>".join(positions))
|
|
180
|
+
|
|
181
|
+
def hcursor_changed(self, marker: Marker) -> None:
|
|
182
|
+
"""Horizontal cursor position has changed
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
marker: marker item
|
|
186
|
+
"""
|
|
187
|
+
_x, y = marker.get_pos()
|
|
188
|
+
self.in_threshold = y
|
|
189
|
+
self.compute_peaks()
|
|
190
|
+
|
|
191
|
+
def minimum_distance_changed(self, value: int) -> None:
|
|
192
|
+
"""Minimum distance changed
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
value: minimum distance value
|
|
196
|
+
"""
|
|
197
|
+
self.min_distance = value
|
|
198
|
+
self.compute_peaks()
|
|
199
|
+
self.get_plot().replot()
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
DataLab main window status bar widgets
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
import psutil
|
|
12
|
+
from guidata.configtools import get_icon
|
|
13
|
+
from guidata.qthelpers import get_std_icon
|
|
14
|
+
from qtpy import QtCore as QC
|
|
15
|
+
from qtpy import QtGui as QG
|
|
16
|
+
from qtpy import QtWidgets as QW
|
|
17
|
+
|
|
18
|
+
from datalab.config import DEBUG, Conf, _
|
|
19
|
+
from datalab.env import execenv
|
|
20
|
+
from datalab.plugins import PluginRegistry
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BaseStatus(QW.QWidget):
|
|
24
|
+
"""Base status widget.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
delay (int | None): update interval (s). If None, widget will not be updated.
|
|
28
|
+
parent (QWidget): parent widget
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self, delay: int | None = None, parent: QW.QWidget | None = None
|
|
33
|
+
) -> None:
|
|
34
|
+
super().__init__(parent)
|
|
35
|
+
layout = QW.QHBoxLayout()
|
|
36
|
+
layout.setContentsMargins(0, 0, 0, 0)
|
|
37
|
+
self.setLayout(layout)
|
|
38
|
+
self.icon = QW.QLabel()
|
|
39
|
+
self.label = QW.QLabel()
|
|
40
|
+
layout.addWidget(self.icon)
|
|
41
|
+
layout.addWidget(self.label)
|
|
42
|
+
if delay is not None:
|
|
43
|
+
self.timer = QC.QTimer()
|
|
44
|
+
self.timer.timeout.connect(self.update_status)
|
|
45
|
+
self.timer.start(delay * 1000)
|
|
46
|
+
|
|
47
|
+
def set_icon(self, icon: QG.QIcon | str | None) -> None:
|
|
48
|
+
"""Set icon.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
icon (QIcon | None): icon
|
|
52
|
+
"""
|
|
53
|
+
size = self.label.sizeHint().height()
|
|
54
|
+
if isinstance(icon, str):
|
|
55
|
+
icon = get_icon(icon)
|
|
56
|
+
pixmap = QG.QPixmap() if icon is None else icon.pixmap(size, size)
|
|
57
|
+
self.icon.setPixmap(pixmap)
|
|
58
|
+
|
|
59
|
+
def update_status(self) -> None:
|
|
60
|
+
"""Update status widget"""
|
|
61
|
+
raise NotImplementedError
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ConsoleStatus(BaseStatus):
|
|
65
|
+
"""Console status widget.
|
|
66
|
+
|
|
67
|
+
Shows a message if an error or warning has been logged to the console.
|
|
68
|
+
Shows a button to show the console, only if the console is hidden.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
parent (QWidget): parent widget
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
SIG_SHOW_CONSOLE = QC.Signal()
|
|
75
|
+
|
|
76
|
+
def __init__(self, parent: QW.QWidget | None = None) -> None:
|
|
77
|
+
super().__init__(None, parent)
|
|
78
|
+
self.label.setText(_("Internal console"))
|
|
79
|
+
self.label.setToolTip(
|
|
80
|
+
_(
|
|
81
|
+
"Click to show the internal console.\n"
|
|
82
|
+
"The icon will turn red if an error or warning is logged."
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
self.label.setCursor(QG.QCursor(QC.Qt.PointingHandCursor))
|
|
86
|
+
self.label.mouseReleaseEvent = self.on_click
|
|
87
|
+
self.ok_icon = get_std_icon("MessageBoxInformation")
|
|
88
|
+
self.ko_icon = get_std_icon("MessageBoxWarning")
|
|
89
|
+
self.has_errors = False
|
|
90
|
+
self.update_status()
|
|
91
|
+
|
|
92
|
+
def on_click(self, event: QG.QMouseEvent) -> None:
|
|
93
|
+
"""Handle mouse click event on label.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
event: mouse event
|
|
97
|
+
"""
|
|
98
|
+
if event.button() == QC.Qt.LeftButton:
|
|
99
|
+
self.SIG_SHOW_CONSOLE.emit()
|
|
100
|
+
|
|
101
|
+
def console_visibility_changed(self, visible: bool) -> None:
|
|
102
|
+
"""Handle console visibility changed event.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
visible (bool): console visibility
|
|
106
|
+
"""
|
|
107
|
+
if visible:
|
|
108
|
+
# Hide this status widget when console is visible
|
|
109
|
+
self.hide()
|
|
110
|
+
else:
|
|
111
|
+
self.show()
|
|
112
|
+
self.update_status()
|
|
113
|
+
|
|
114
|
+
def exception_occurred(self) -> None:
|
|
115
|
+
"""Handle exception occurred event"""
|
|
116
|
+
self.has_errors = True
|
|
117
|
+
self.update_status()
|
|
118
|
+
|
|
119
|
+
def update_status(self) -> None:
|
|
120
|
+
"""Update status widget"""
|
|
121
|
+
if self.has_errors:
|
|
122
|
+
self.set_icon(self.ko_icon)
|
|
123
|
+
self.label.setStyleSheet("color: red")
|
|
124
|
+
self.label.setToolTip(
|
|
125
|
+
_(
|
|
126
|
+
"Click to show the internal console.\n"
|
|
127
|
+
"An error or warning has been logged."
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
else:
|
|
131
|
+
self.set_icon(self.ok_icon)
|
|
132
|
+
self.label.setStyleSheet("")
|
|
133
|
+
self.label.setToolTip(
|
|
134
|
+
_(
|
|
135
|
+
"Click to show the internal console.\n"
|
|
136
|
+
"No error or warning has been logged."
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class MemoryStatus(BaseStatus):
|
|
142
|
+
"""Memory status widget.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
threshold (int): available memory thresold (MB)
|
|
146
|
+
delay (int): update interval (s)
|
|
147
|
+
parent (QWidget): parent widget
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
SIG_MEMORY_ALARM = QC.Signal(bool)
|
|
151
|
+
|
|
152
|
+
def __init__(
|
|
153
|
+
self, threshold: int = 500, delay: int = 2, parent: QW.QWidget | None = None
|
|
154
|
+
) -> None:
|
|
155
|
+
super().__init__(delay, parent)
|
|
156
|
+
self.demo_mode = False
|
|
157
|
+
self.ko_icon = get_std_icon("MessageBoxWarning")
|
|
158
|
+
self.__threshold = threshold * (1024**2)
|
|
159
|
+
self.label.setMinimumWidth(self.label.fontMetrics().width("000%"))
|
|
160
|
+
self.update_status()
|
|
161
|
+
|
|
162
|
+
def set_demo_mode(self, state: bool) -> None:
|
|
163
|
+
"""Set demo mode state (used when taking screenshots).
|
|
164
|
+
The demo mode allows to take screenshots which always look the same.
|
|
165
|
+
(this will set memory usage to a constant value).
|
|
166
|
+
If demo mode is set to False, memory usage will be set to actual value.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
state (bool): demo mode state
|
|
170
|
+
"""
|
|
171
|
+
self.demo_mode = state
|
|
172
|
+
self.update_status()
|
|
173
|
+
|
|
174
|
+
def update_status(self) -> None:
|
|
175
|
+
"""Update status widget"""
|
|
176
|
+
mem = psutil.virtual_memory()
|
|
177
|
+
memok = mem.available > self.__threshold
|
|
178
|
+
self.SIG_MEMORY_ALARM.emit(not memok)
|
|
179
|
+
txtlist = [
|
|
180
|
+
f"%s {mem.available // (1024**2)} MB" % _("Memory available:"),
|
|
181
|
+
f"%s {mem.used // (1024**2)} MB" % _("Memory used:"),
|
|
182
|
+
f"%s {self.__threshold // (1024**2)} MB" % _("Alarm threshold:"),
|
|
183
|
+
]
|
|
184
|
+
txt = os.linesep.join(txtlist)
|
|
185
|
+
self.setToolTip(txt)
|
|
186
|
+
if DEBUG and not memok:
|
|
187
|
+
execenv.log(self, txt)
|
|
188
|
+
self.label.setStyleSheet("" if memok else "color: red")
|
|
189
|
+
self.set_icon("libre-tech-ram.svg" if memok else self.ko_icon)
|
|
190
|
+
mem_percent = 65 if self.demo_mode else int(mem.percent)
|
|
191
|
+
self.label.setText(_("Memory:") + f" {mem_percent}%")
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class PluginStatus(BaseStatus):
|
|
195
|
+
"""Plugin status widget.
|
|
196
|
+
Shows the number of plugins loaded.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
parent (QWidget): parent widget
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
def __init__(self, parent: QW.QWidget | None = None) -> None:
|
|
203
|
+
super().__init__(None, parent)
|
|
204
|
+
self.set_icon("libre-gui-plugin.svg")
|
|
205
|
+
self.update_status()
|
|
206
|
+
|
|
207
|
+
def update_status(self) -> None:
|
|
208
|
+
"""Update status widget"""
|
|
209
|
+
text = _("Plugins:") + " "
|
|
210
|
+
if Conf.main.plugins_enabled.get():
|
|
211
|
+
nplugins = len(PluginRegistry.get_plugins())
|
|
212
|
+
text += str(nplugins)
|
|
213
|
+
else:
|
|
214
|
+
text += "-"
|
|
215
|
+
self.label.setText(text)
|
|
216
|
+
self.setToolTip(PluginRegistry.get_plugin_info())
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class XMLRPCStatus(BaseStatus):
|
|
220
|
+
"""XML-RPC status widget.
|
|
221
|
+
Shows the XML-RPC server status and port number.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
parent (QWidget): parent widget
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
def __init__(self, parent: QW.QWidget | None = None) -> None:
|
|
228
|
+
super().__init__(None, parent)
|
|
229
|
+
self.port: int | None = None
|
|
230
|
+
|
|
231
|
+
def set_port(self, port: int | None):
|
|
232
|
+
"""Set XML-RPC server port number.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
port (int | None): XML-RPC server port number.
|
|
236
|
+
If None, XML-RPC server is disabled.
|
|
237
|
+
"""
|
|
238
|
+
self.port = port
|
|
239
|
+
self.update_status()
|
|
240
|
+
|
|
241
|
+
def update_status(self) -> None:
|
|
242
|
+
"""Update status widget"""
|
|
243
|
+
text = _("XML-RPC:") + " "
|
|
244
|
+
if self.port is None:
|
|
245
|
+
self.label.setText(text + "-")
|
|
246
|
+
self.set_icon("libre-gui-unlink.svg")
|
|
247
|
+
else:
|
|
248
|
+
self.label.setText(text + str(self.port))
|
|
249
|
+
self.set_icon("libre-gui-link.svg")
|