├── .coveragerc ├── .env.template ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── doc_request.md │ ├── feature_request.md │ └── tutorial_request.md └── workflows │ └── test_pyqt5.yml ├── .gitignore ├── .pylintrc ├── .readthedocs.yaml ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DataLab-demo.bat ├── DataLab.bat ├── DataLab.desktop ├── DataLab.spec ├── LICENSE ├── MANIFEST.in ├── README.md ├── cdl ├── __init__.py ├── algorithms │ ├── __init__.py │ ├── coordinates.py │ ├── datatypes.py │ ├── image.py │ └── signal.py ├── app.py ├── computation │ ├── __init__.py │ ├── base.py │ ├── image │ │ ├── __init__.py │ │ ├── detection.py │ │ ├── edges.py │ │ ├── exposure.py │ │ ├── morphology.py │ │ ├── restoration.py │ │ └── threshold.py │ └── signal.py ├── config.py ├── core │ ├── __init__.py │ ├── baseproxy.py │ ├── gui │ │ ├── __init__.py │ │ ├── actionhandler.py │ │ ├── docks.py │ │ ├── h5io.py │ │ ├── macroeditor.py │ │ ├── main.py │ │ ├── objectmodel.py │ │ ├── objectview.py │ │ ├── panel │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── image.py │ │ │ ├── macro.py │ │ │ └── signal.py │ │ ├── plothandler.py │ │ ├── processor │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── catcher.py │ │ │ ├── image.py │ │ │ └── signal.py │ │ ├── profiledialog.py │ │ ├── roieditor.py │ │ ├── settings.py │ │ └── tour.py │ ├── io │ │ ├── __init__.py │ │ ├── base.py │ │ ├── conv.py │ │ ├── h5 │ │ │ ├── __init__.py │ │ │ ├── common.py │ │ │ ├── generic.py │ │ │ └── utils.py │ │ ├── image │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── formats.py │ │ │ └── funcs.py │ │ ├── native.py │ │ └── signal │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── formats.py │ │ │ └── funcs.py │ ├── model │ │ ├── __init__.py │ │ ├── base.py │ │ ├── image.py │ │ └── signal.py │ └── remote.py ├── data │ ├── dependencies-py3-win32.txt │ ├── icons │ │ ├── analysis │ │ │ ├── delete_results.svg │ │ │ ├── fw1e2.svg │ │ │ ├── fwhm.svg │ │ │ ├── histogram.svg │ │ │ ├── peak_detect.svg │ │ │ ├── plot_results.svg │ │ │ ├── show_results.svg │ │ │ └── stats.svg │ │ ├── apply.svg │ │ ├── check_all.svg │ │ ├── collapse.svg │ │ ├── collapse_selection.svg │ │ ├── edit.svg │ │ ├── edit │ │ │ ├── copy_titles.svg │ │ │ ├── delete.svg │ │ │ ├── delete_all.svg │ │ │ ├── duplicate.svg │ │ │ ├── image_roi.svg │ │ │ ├── metadata_copy.svg │ │ │ ├── metadata_delete.svg │ │ │ ├── metadata_export.svg │ │ │ ├── metadata_import.svg │ │ │ ├── metadata_paste.svg │ │ │ ├── move_down.svg │ │ │ ├── move_up.svg │ │ │ ├── new_group.svg │ │ │ ├── rename.svg │ │ │ ├── roi.svg │ │ │ ├── roi_coordinate.svg │ │ │ ├── roi_delete.svg │ │ │ ├── roi_graphical.svg │ │ │ ├── roi_new.svg │ │ │ ├── roi_new_circle.svg │ │ │ ├── roi_new_polygon.svg │ │ │ ├── roi_new_rectangle.svg │ │ │ └── signal_roi.svg │ │ ├── expand.svg │ │ ├── expand_selection.svg │ │ ├── fit │ │ │ ├── cdffit.svg │ │ │ ├── expfit.svg │ │ │ ├── gaussfit.svg │ │ │ ├── linearfit.svg │ │ │ ├── lorentzfit.svg │ │ │ ├── multigaussfit.svg │ │ │ ├── polyfit.svg │ │ │ ├── sinfit.svg │ │ │ └── voigtfit.svg │ │ ├── group.svg │ │ ├── h5 │ │ │ ├── h5array.svg │ │ │ ├── h5attrs.svg │ │ │ ├── h5browser.svg │ │ │ ├── h5file.svg │ │ │ ├── h5group.svg │ │ │ └── h5scalar.svg │ │ ├── help_pdf.svg │ │ ├── image.svg │ │ ├── io │ │ │ ├── fileopen_directory.svg │ │ │ ├── fileopen_h5.svg │ │ │ ├── fileopen_ima.svg │ │ │ ├── fileopen_py.svg │ │ │ ├── fileopen_sig.svg │ │ │ ├── filesave_h5.svg │ │ │ ├── filesave_ima.svg │ │ │ ├── filesave_py.svg │ │ │ ├── filesave_sig.svg │ │ │ └── import_text.svg │ │ ├── libre-camera-flash-off.svg │ │ ├── libre-camera-flash-on.svg │ │ ├── libre-gui-about.svg │ │ ├── libre-gui-action-delete.svg │ │ ├── libre-gui-add.svg │ │ ├── libre-gui-arrow-down.svg │ │ ├── libre-gui-arrow-left.svg │ │ ├── libre-gui-arrow-right.svg │ │ ├── libre-gui-arrow-up.svg │ │ ├── libre-gui-close.svg │ │ ├── libre-gui-cogs.svg │ │ ├── libre-gui-globe.svg │ │ ├── libre-gui-help.svg │ │ ├── libre-gui-link.svg │ │ ├── libre-gui-menu.svg │ │ ├── libre-gui-pencil.svg │ │ ├── libre-gui-plugin.svg │ │ ├── libre-gui-questions.svg │ │ ├── libre-gui-settings.svg │ │ ├── libre-gui-unlink.svg │ │ ├── libre-tech-ram.svg │ │ ├── libre-toolbox.svg │ │ ├── logs.svg │ │ ├── menu.svg │ │ ├── new_image.svg │ │ ├── new_signal.svg │ │ ├── operations │ │ │ ├── abs.svg │ │ │ ├── arithmetic.svg │ │ │ ├── average.svg │ │ │ ├── constant.svg │ │ │ ├── constant_add.svg │ │ │ ├── constant_divide.svg │ │ │ ├── constant_multiply.svg │ │ │ ├── constant_substract.svg │ │ │ ├── convert_dtype.svg │ │ │ ├── convolution.svg │ │ │ ├── derivative.svg │ │ │ ├── difference.svg │ │ │ ├── distribute_on_grid.svg │ │ │ ├── division.svg │ │ │ ├── exp.svg │ │ │ ├── flip_horizontally.svg │ │ │ ├── flip_vertically.svg │ │ │ ├── im.svg │ │ │ ├── integral.svg │ │ │ ├── inverse.svg │ │ │ ├── log10.svg │ │ │ ├── power.svg │ │ │ ├── product.svg │ │ │ ├── profile.svg │ │ │ ├── profile_average.svg │ │ │ ├── profile_radial.svg │ │ │ ├── profile_segment.svg │ │ │ ├── quadratic_difference.svg │ │ │ ├── re.svg │ │ │ ├── reset_positions.svg │ │ │ ├── rotate_left.svg │ │ │ ├── rotate_right.svg │ │ │ ├── sqrt.svg │ │ │ └── sum.svg │ │ ├── play_demo.svg │ │ ├── processing │ │ │ ├── axis_transform.svg │ │ │ ├── bandpass.svg │ │ │ ├── bandstop.svg │ │ │ ├── binning.svg │ │ │ ├── clip.svg │ │ │ ├── detrending.svg │ │ │ ├── edges.svg │ │ │ ├── exposure.svg │ │ │ ├── fourier.svg │ │ │ ├── highpass.svg │ │ │ ├── interpolation.svg │ │ │ ├── level_adjustment.svg │ │ │ ├── lowpass.svg │ │ │ ├── morphology.svg │ │ │ ├── noise_reduction.svg │ │ │ ├── normalize.svg │ │ │ ├── offset_correction.svg │ │ │ ├── resampling.svg │ │ │ ├── resize.svg │ │ │ ├── reverse_signal_x.svg │ │ │ ├── stability.svg │ │ │ ├── swap_x_y.svg │ │ │ ├── thresholding.svg │ │ │ └── windowing.svg │ │ ├── reset.svg │ │ ├── restore.svg │ │ ├── signal.svg │ │ ├── table.svg │ │ ├── table_unavailable.svg │ │ ├── to_signal.svg │ │ ├── tour │ │ │ ├── next.svg │ │ │ ├── previous.svg │ │ │ ├── rewind.svg │ │ │ ├── stop.svg │ │ │ └── tour.svg │ │ ├── uncheck_all.svg │ │ └── view │ │ │ ├── annotations.svg │ │ │ ├── curve_antialiasing.svg │ │ │ ├── new_window.svg │ │ │ ├── refresh-auto.svg │ │ │ ├── refresh-manual.svg │ │ │ ├── reset_curve_styles.svg │ │ │ ├── show_first.svg │ │ │ └── show_titles.svg │ ├── logo │ │ ├── DataLab-Banner-150.png │ │ ├── DataLab-Banner-200.png │ │ ├── DataLab-Banner2-100.png │ │ ├── DataLab-Splash.png │ │ ├── DataLab-watermark.png │ │ └── DataLab.svg │ └── tests │ │ ├── annotations.json │ │ ├── curve_formats │ │ ├── bandwidth.txt │ │ ├── dynamic_parameters.txt │ │ ├── fw1e2.txt │ │ ├── fwhm.txt │ │ ├── multiple_curves.csv │ │ ├── noised_saw.mat │ │ ├── oscilloscope.csv │ │ ├── other │ │ │ ├── other2 │ │ │ │ └── recursive2.txt │ │ │ └── recursive1.txt │ │ ├── paracetamol.npy │ │ ├── paracetamol.txt │ │ ├── paracetamol_dx_dy.csv │ │ ├── paracetamol_dy.csv │ │ └── simple.txt │ │ ├── empty.h5 │ │ ├── fabry-perot1.jpg │ │ ├── fabry-perot2.jpg │ │ ├── flower.npy │ │ ├── image_formats │ │ ├── NF 180338201.scor-data │ │ ├── binary_image.npy │ │ ├── binary_image.png │ │ ├── fiber.bmp │ │ ├── fiber.csv │ │ ├── fiber.jpg │ │ ├── fiber.png │ │ ├── fiber.txt │ │ ├── mr-brain.dcm │ │ ├── noised_gaussian.mat │ │ ├── sif_reader │ │ │ ├── nd_lum_image_no_glue.sif │ │ │ ├── raman1.sif │ │ │ └── sif_reader-LICENSE │ │ ├── uint16.tiff │ │ └── uint8.tiff │ │ ├── laser_beam │ │ ├── TEM00_z_13.jpg │ │ ├── TEM00_z_18.jpg │ │ ├── TEM00_z_23.jpg │ │ ├── TEM00_z_30.jpg │ │ ├── TEM00_z_35.jpg │ │ ├── TEM00_z_40.jpg │ │ ├── TEM00_z_45.jpg │ │ ├── TEM00_z_50.jpg │ │ ├── TEM00_z_55.jpg │ │ ├── TEM00_z_60.jpg │ │ ├── TEM00_z_65.jpg │ │ ├── TEM00_z_70.jpg │ │ ├── TEM00_z_75.jpg │ │ └── TEM00_z_80.jpg │ │ └── reordering_test.h5 ├── env.py ├── locale │ └── fr │ │ └── LC_MESSAGES │ │ └── cdl.po ├── obj.py ├── param.py ├── plugins.py ├── plugins │ ├── _readme_.txt │ ├── cdl_imageformats.py │ └── cdl_testdata.py ├── proxy.py ├── start.pyw ├── tests │ ├── __init__.py │ ├── backbone │ │ ├── __init__.py │ │ ├── config_unit_test.py │ │ ├── dictlistserial_app_test.py │ │ ├── errorcatcher_unit_test.py │ │ ├── errormsgbox_unit_test.py │ │ ├── execenv_unit.py │ │ ├── loadtest_gdi.py │ │ ├── long_callback.py │ │ ├── main_app_test.py │ │ ├── memory_leak.py │ │ ├── procisolation1_unit.py │ │ ├── procisolation2_unit.py │ │ ├── procisolation_unit_test.py │ │ └── profiling_app.py │ ├── conftest.py │ ├── data.py │ ├── features │ │ ├── __init__.py │ │ ├── applauncher │ │ │ ├── __init__.py │ │ │ ├── launcher1_app_test.py │ │ │ └── launcher2_app_test.py │ │ ├── common │ │ │ ├── __init__.py │ │ │ ├── arithmeticparam_unit_test.py │ │ │ ├── io1_unit_test.py │ │ │ ├── io2_unit_test.py │ │ │ ├── io_app_test.py │ │ │ ├── metadata_app_test.py │ │ │ ├── metadata_io_unit_test.py │ │ │ ├── misc_app_test.py │ │ │ ├── newobject_unit_test.py │ │ │ ├── operation_modes_app_test.py │ │ │ ├── reorder_app_test.py │ │ │ ├── resultproperties_app_test.py │ │ │ ├── resultshapes_app_test.py │ │ │ ├── roi_app_test.py │ │ │ ├── roieditor_unit_test.py │ │ │ ├── roiobjects_unit_test.py │ │ │ ├── stat_app_test.py │ │ │ ├── stat_unit_test.py │ │ │ ├── stats_tools_unit_test.py │ │ │ └── textimport_unit_test.py │ │ ├── control │ │ │ ├── __init__.py │ │ │ ├── connect_dialog.py │ │ │ ├── embedded1_unit_test.py │ │ │ ├── embedded2_unit_test.py │ │ │ ├── remoteclient_app_test.py │ │ │ └── remoteclient_unit.py │ │ ├── hdf5 │ │ │ ├── __init__.py │ │ │ ├── h5browser1_unit_test.py │ │ │ ├── h5browser2_unit.py │ │ │ ├── h5browser_app_test.py │ │ │ └── h5importer_app_test.py │ │ ├── images │ │ │ ├── __init__.py │ │ │ ├── annotations_app_test.py │ │ │ ├── annotations_unit_test.py │ │ │ ├── average_app_test.py │ │ │ ├── binning_unit_test.py │ │ │ ├── blobs_app_test.py │ │ │ ├── centroid_unit_test.py │ │ │ ├── contour_app_test.py │ │ │ ├── contour_fabryperot_app_test.py │ │ │ ├── contour_unit_test.py │ │ │ ├── datatype_unit_test.py │ │ │ ├── denoise_app_test.py │ │ │ ├── distribute_on_grid_app_test.py │ │ │ ├── edges_app_test.py │ │ │ ├── enclosingcircle_unit_test.py │ │ │ ├── fft2d_app_test.py │ │ │ ├── fft2d_unit_test.py │ │ │ ├── flatfield_app_test.py │ │ │ ├── hough_circle_unit_test.py │ │ │ ├── imagetools_app_test.py │ │ │ ├── imagetools_unit_test.py │ │ │ ├── load_app_test.py │ │ │ ├── morph_app_test.py │ │ │ ├── offset_correction_unit_test.py │ │ │ ├── operation_unit_test.py │ │ │ ├── peak2d_app_test.py │ │ │ ├── peak2d_limits_unit.py │ │ │ ├── peak2d_unit_test.py │ │ │ ├── processing_unit_test.py │ │ │ ├── profile_app_test.py │ │ │ ├── profile_unit_test.py │ │ │ ├── roi2dparam_unit_test.py │ │ │ ├── roi_circ_app_test.py │ │ │ ├── select_background_unit_test.py │ │ │ └── spectrum2d_unit_test.py │ │ ├── macro │ │ │ ├── __init__.py │ │ │ ├── macro_app_test.py │ │ │ └── macroeditor_unit_test.py │ │ ├── signals │ │ │ ├── __init__.py │ │ │ ├── analysis_unit_test.py │ │ │ ├── deltax_dialog_unit_test.py │ │ │ ├── fft1d_app_test.py │ │ │ ├── fft1d_unit_test.py │ │ │ ├── fitdialog_unit_test.py │ │ │ ├── fwhm_unit_test.py │ │ │ ├── loadbigsignal_app_test.py │ │ │ ├── offset_correction_unit_test.py │ │ │ ├── operation_unit_test.py │ │ │ ├── peak1d_unit_test.py │ │ │ ├── processing_unit_test.py │ │ │ ├── select_baseline_unit_test.py │ │ │ ├── select_xy_cursor_unit_test.py │ │ │ ├── spectrum1d_unit_test.py │ │ │ └── stability_unit_test.py │ │ ├── tour_unit_test.py │ │ └── utilities │ │ │ ├── __init__.py │ │ │ ├── installconf_unit_test.py │ │ │ ├── logview_app_test.py │ │ │ ├── logview_error.py │ │ │ ├── logview_unit_test.py │ │ │ ├── memstatus_app_test.py │ │ │ └── settings_unit_test.py │ └── scenarios │ │ ├── __init__.py │ │ ├── beautiful_app.py │ │ ├── common.py │ │ ├── demo.py │ │ ├── example_app_test.py │ │ ├── scenario_h5_app_test.py │ │ ├── scenario_ima1_app_test.py │ │ ├── scenario_ima2_app_test.py │ │ ├── scenario_mac_app_test.py │ │ ├── scenario_sig1_app_test.py │ │ └── scenario_sig2_app_test.py ├── utils │ ├── __init__.py │ ├── conf.py │ ├── dephash.py │ ├── io.py │ ├── misc.py │ ├── qthelpers.py │ ├── strings.py │ ├── tests.py │ └── vistools.py └── widgets │ ├── __init__.py │ ├── connection.py │ ├── fileviewer.py │ ├── fitdialog.py │ ├── h5browser.py │ ├── imagebackground.py │ ├── instconfviewer.py │ ├── logviewer.py │ ├── signalbaseline.py │ ├── signalcursor.py │ ├── signaldeltax.py │ ├── signalpeak.py │ ├── status.py │ ├── textimport.py │ ├── warningerror.py │ └── wizard.py ├── create_dephash.py ├── doc ├── _static │ ├── DataLab-Frontpage.png │ ├── DataLab-Title.png │ ├── DataLab-Title.svg │ ├── codra.png │ ├── favicon.ico │ ├── plotpy-stack-powered.png │ └── pypi.svg ├── _templates │ └── layout.html ├── api │ ├── algorithms.rst │ ├── computation.rst │ ├── core.gui │ │ ├── actionhandler.rst │ │ ├── docks.rst │ │ ├── h5io.rst │ │ ├── index.rst │ │ ├── main.rst │ │ ├── objectview.rst │ │ ├── panel.rst │ │ ├── plothandler.rst │ │ ├── processor.rst │ │ └── roieditor.rst │ ├── index.rst │ ├── obj.rst │ ├── param.rst │ └── proxy.rst ├── conf.py ├── contributing │ ├── contribute_code.rst │ ├── environment.md │ ├── gitworkflow.rst │ ├── guidelines.rst │ ├── index.rst │ └── roadmap.md ├── features │ ├── general │ │ ├── command.rst │ │ ├── h5browser.rst │ │ ├── instviewer.rst │ │ ├── logviewer.rst │ │ ├── macros.rst │ │ ├── model.rst │ │ ├── plugins.rst │ │ ├── remote.rst │ │ ├── settings.rst │ │ └── workspace.rst │ ├── image │ │ ├── 2d_peak_detection.rst │ │ ├── contour_detection.rst │ │ ├── menu_analysis.rst │ │ ├── menu_edit.rst │ │ ├── menu_file.rst │ │ ├── menu_operations.rst │ │ ├── menu_processing.rst │ │ └── menu_view.rst │ ├── index.rst │ ├── signal │ │ ├── menu_analysis.rst │ │ ├── menu_edit.rst │ │ ├── menu_file.rst │ │ ├── menu_operations.rst │ │ ├── menu_processing.rst │ │ └── menu_view.rst │ └── validation │ │ ├── functional.rst │ │ ├── status.rst │ │ └── technical.rst ├── images │ ├── 2d_peak_detection │ │ ├── peak2d_app_param.png │ │ ├── peak2d_app_results.png │ │ └── peak2d_app_zoom.png │ ├── 2dpeak_detection.png │ ├── DataLab-Overview.png │ ├── DataLab-Screenshot-Image.png │ ├── DataLab-Screenshot-Signal.png │ ├── DataLab-Screenshot-Theme.png │ ├── DataLab-Screenshot.png │ ├── DataLab-banner.png │ ├── annotations │ │ ├── image_annotations1.png │ │ ├── image_annotations2.png │ │ ├── signal_annotations1.png │ │ ├── signal_annotations2.png │ │ └── view_menu_entry.png │ ├── contour_detection.png │ ├── contour_detection │ │ ├── contour_app.png │ │ ├── contour_app_param.png │ │ └── contour_app_results.png │ ├── h5browser.png │ ├── import_text_file │ │ ├── i_01.png │ │ ├── i_02.png │ │ ├── i_03.png │ │ ├── i_04.png │ │ ├── s_01.png │ │ ├── s_02.png │ │ ├── s_03.png │ │ └── s_04.png │ ├── interactive_tests.png │ ├── logos │ │ ├── DataLab-WinPython.png │ │ ├── NumPy.png │ │ ├── OpenCV.png │ │ ├── Python.png │ │ ├── SciPy.png │ │ ├── cea.svg │ │ ├── codra.svg │ │ ├── nlnet.svg │ │ ├── plotpystack.png │ │ └── scikit-image.png │ ├── multi_gaussian_fit.png │ ├── peak_detection.png │ ├── settings.png │ ├── shots │ │ ├── about.png │ │ ├── connect_dialog.png │ │ ├── doc_online.png │ │ ├── i_analysis.png │ │ ├── i_beautiful.png │ │ ├── i_contour_test.png │ │ ├── i_edit.png │ │ ├── i_file.png │ │ ├── i_help.png │ │ ├── i_histogram.png │ │ ├── i_new_window.png │ │ ├── i_operation.png │ │ ├── i_peak2d_test.png │ │ ├── i_processing.png │ │ ├── i_profile.png │ │ ├── i_profile_average.png │ │ ├── i_roi_dialog.png │ │ ├── i_roi_image.png │ │ ├── i_stats.png │ │ ├── i_view.png │ │ ├── instviewer.png │ │ ├── instviewer2.png │ │ ├── instviewer3.png │ │ ├── logviewer.png │ │ ├── macro_panel.png │ │ ├── remote_control_test.png │ │ ├── s_analysis.png │ │ ├── s_app_at_startup.png │ │ ├── s_beautiful.png │ │ ├── s_edit.png │ │ ├── s_file.png │ │ ├── s_fwhm.png │ │ ├── s_help.png │ │ ├── s_histogram.png │ │ ├── s_new_window.png │ │ ├── s_operation.png │ │ ├── s_peak_detection.png │ │ ├── s_processing.png │ │ ├── s_roi_dialog.png │ │ ├── s_roi_signal.png │ │ ├── s_stats.png │ │ ├── s_view.png │ │ ├── windows_installer.png │ │ └── wpcp.png │ └── tutorials │ │ ├── blobs │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ ├── 04.png │ │ ├── 05.png │ │ ├── 06.png │ │ ├── 07.png │ │ ├── 08.png │ │ ├── 09.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ └── 13.png │ │ ├── csection.png │ │ ├── custom_func │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ ├── 04.png │ │ ├── 05.png │ │ ├── 06.png │ │ ├── 07.png │ │ ├── 08.png │ │ ├── 09.png │ │ ├── 10.png │ │ ├── 11.png │ │ └── nb.png │ │ ├── fabry_perot │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ ├── 04.png │ │ ├── 05.png │ │ ├── 06.png │ │ ├── 07.png │ │ ├── 08.png │ │ ├── 09.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 23.png │ │ ├── 24.png │ │ ├── 25.png │ │ ├── 26.png │ │ ├── 27.png │ │ ├── 28.png │ │ ├── 29.png │ │ ├── 30.png │ │ └── default_colormap.png │ │ ├── imagestats.png │ │ ├── laser_beam │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ ├── 04.png │ │ ├── 05.png │ │ ├── 06.png │ │ ├── 07.png │ │ ├── 08.png │ │ ├── 09.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ └── 18.png │ │ ├── spectrum │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ ├── 04.png │ │ ├── 05.png │ │ ├── 06.png │ │ ├── 07.png │ │ ├── 08.png │ │ ├── 09.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 20.png │ │ └── 21.png │ │ └── work_with_spyder │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ └── spyder_and_datalab.png ├── index.rst ├── intro │ ├── index.rst │ ├── installation.rst │ ├── introduction.rst │ ├── keyfeatures.rst │ └── tutorials │ │ ├── blobs.rst │ │ ├── custom_func.ipynb │ │ ├── custom_func.py │ │ ├── custom_func.rst │ │ ├── fabry_perot.rst │ │ ├── index.rst │ │ ├── laser_beam.rst │ │ ├── my_work.py │ │ ├── my_work_debug_with_cdl.py │ │ ├── my_work_test_with_cdl.py │ │ ├── spectrum.rst │ │ ├── videos │ │ ├── p1_quick_demo.rst │ │ └── p2_extensibility.rst │ │ └── work_with_spyder.rst ├── locale │ └── fr │ │ └── LC_MESSAGES │ │ ├── api │ │ ├── algorithms.po │ │ ├── computation.po │ │ ├── core.gui │ │ │ ├── actionhandler.po │ │ │ ├── docks.po │ │ │ ├── h5io.po │ │ │ ├── index.po │ │ │ ├── main.po │ │ │ ├── objectview.po │ │ │ ├── panel.po │ │ │ ├── plothandler.po │ │ │ ├── processor.po │ │ │ └── roieditor.po │ │ ├── index.po │ │ ├── obj.po │ │ ├── param.po │ │ └── proxy.po │ │ ├── contributing │ │ ├── changelog.po │ │ ├── contribute_code.po │ │ ├── environment.po │ │ ├── gitworkflow.po │ │ ├── guidelines.po │ │ ├── index.po │ │ └── roadmap.po │ │ ├── features │ │ ├── general │ │ │ ├── command.po │ │ │ ├── h5browser.po │ │ │ ├── instviewer.po │ │ │ ├── logviewer.po │ │ │ ├── macros.po │ │ │ ├── model.po │ │ │ ├── plugins.po │ │ │ ├── remote.po │ │ │ ├── settings.po │ │ │ └── workspace.po │ │ ├── image │ │ │ ├── 2d_peak_detection.po │ │ │ ├── contour_detection.po │ │ │ ├── menu_analysis.po │ │ │ ├── menu_edit.po │ │ │ ├── menu_file.po │ │ │ ├── menu_operations.po │ │ │ ├── menu_processing.po │ │ │ └── menu_view.po │ │ ├── index.po │ │ ├── signal │ │ │ ├── menu_analysis.po │ │ │ ├── menu_edit.po │ │ │ ├── menu_file.po │ │ │ ├── menu_operations.po │ │ │ ├── menu_processing.po │ │ │ └── menu_view.po │ │ └── validation │ │ │ ├── functional.po │ │ │ ├── status.po │ │ │ └── technical.po │ │ ├── index.po │ │ ├── intro │ │ ├── index.po │ │ ├── installation.po │ │ ├── introduction.po │ │ ├── keyfeatures.po │ │ └── tutorials │ │ │ ├── blobs.po │ │ │ ├── custom_func.po │ │ │ ├── fabry_perot.po │ │ │ ├── index.po │ │ │ ├── laser_beam.po │ │ │ ├── spectrum.po │ │ │ ├── videos │ │ │ ├── p1_quick_demo.po │ │ │ └── p2_extensibility.po │ │ │ └── work_with_spyder.po │ │ └── requirements.po ├── processor_methods_image.csv ├── processor_methods_nb.csv ├── processor_methods_signal.csv ├── remote_example.ipynb ├── remote_example.py ├── remotecontrol_py27.py ├── requirements.rst ├── update_processor_methods.py ├── update_requirements.py ├── update_screenshots.py ├── update_validation_status.py ├── validation_statistics.csv ├── validation_status_image.csv └── validation_status_signal.csv ├── macros └── examples │ ├── imageproc_macro.py │ └── simple_macro.py ├── plugins └── examples │ ├── cdl_custom_func.py │ ├── cdl_example_empty.py │ ├── cdl_example_imageformat.py │ └── cdl_example_imageproc.py ├── pyproject.toml ├── requirements.txt ├── resources ├── DataLab-Banner.svg ├── DataLab-Banner2.svg ├── DataLab-Banner3.svg ├── DataLab-Debug.svg ├── DataLab-Frontpage.svg ├── DataLab-Overview-Large.svg ├── DataLab-Overview.svg ├── DataLab-Panorama.svg ├── DataLab-Reset.ico ├── DataLab-Reset.svg ├── DataLab-Screenshot-Theme.svg ├── DataLab-Splash.svg ├── DataLab-Sticker.svg ├── DataLab-Title-DarkBG.svg ├── DataLab-Title.svg ├── DataLab-Wallpaper.svg ├── DataLab-Windows-Installer.svg ├── DataLab-app.svg ├── DataLab-lib.svg ├── DataLab-remote.svg ├── DataLab-watermark.svg ├── DataLab.ico ├── DataLab.svg ├── WixUIBanner.svg ├── WixUIDialog.svg ├── api-ms-win-core-path-l1-1-0.dll ├── api-ms-win-core-path-l1-1-0.txt └── deploy.bat ├── scripts ├── _tests_.bat ├── build_dist.bat ├── build_doc.bat ├── build_doc_html.bat ├── build_exe.bat ├── build_ghpages.bat ├── build_installer.bat ├── clean_up.bat ├── gettext.bat ├── gettext_scan.bat ├── preview_ghpages.bat ├── release.bat ├── run_coverage.bat ├── run_pylint.bat ├── run_pytest.bat ├── run_pytest_on_all.bat ├── run_ruff.bat ├── run_test_launcher.bat ├── update_doc_resources.bat ├── upgrade_all.bat ├── upgrade_stack.bat ├── upload_ghpages.bat └── utils.bat └── wix ├── generic-DataLab.wxs ├── license.rtf └── makewxs.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | 3 | #--- Ignore this warning because the process isolation feature of DataLab 4 | #--- causes coverage to report 0% coverage when no computation is performed 5 | #--- in the isolated process during the session. 6 | disable_warnings = no-data-collected 7 | 8 | parallel = True 9 | concurrency = multiprocessing,thread 10 | 11 | omit = 12 | */cdl/utils/tests.py 13 | */cdl/tests/* 14 | */guidata/* 15 | */plotpy/* 16 | 17 | #--- Workaround for certain builds of python-opencv package: 18 | ./config-3.py 19 | ./config.py 20 | #--- 21 | 22 | [report] 23 | exclude_also = 24 | def __repr__ 25 | if __name__ == .__main__.: 26 | if TYPE_CHECKING: 27 | if DEBUG[\s]*: 28 | if self.__debug[\s]*: 29 | -------------------------------------------------------------------------------- /.env.template: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Installation information** 28 | 29 | - DataLab installation type ["Python package" or "stand-alone Windows version"] 30 | - Copy/paste here the contents of "About DataLab installation..." window (Menu "?") 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/doc_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation request 3 | about: Ask for documentation about a specific topic 4 | title: '' 5 | labels: documentation 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your documentation request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the topic you would like to be covered** 14 | A clear and concise description of what you want to be documented. 15 | 16 | **Describe the nature of the documentation you would like to see** 17 | Tutorial, reference, etc. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/tutorial_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Tutorial request 3 | about: Ask for a tutorial on a specific topic 4 | title: '' 5 | labels: documentation 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the context and technical field of the tutorial you would like to see** 11 | A clear and concise description of your technical field, and of the specific application. 12 | 13 | **Describe the topic you would like to be covered** 14 | A clear and concise description of what you want to be documented. 15 | 16 | **Describe the features you would like to see in the tutorial** 17 | A clear and concise description of the features you would like to see in the tutorial. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | 22 | _Please attach an example data set, if possible. 23 | And please confirm that you are willing to share this data set under the terms of DataLab's license._ 24 | -------------------------------------------------------------------------------- /.github/workflows/test_pyqt5.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python 3 | 4 | # Inspired from https://pytest-qt.readthedocs.io/en/latest/troubleshooting.html#github-actions 5 | 6 | name: Install and Test on Ubuntu (latest) with PyQt5 7 | 8 | on: 9 | push: 10 | branches: [ "main", "develop" ] 11 | pull_request: 12 | branches: [ "main", "develop" ] 13 | 14 | jobs: 15 | build: 16 | 17 | env: 18 | DISPLAY: ':99.0' 19 | 20 | runs-on: ubuntu-latest 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | python-version: ["3.9", "3.13"] 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | - name: Set up Python ${{ matrix.python-version }} 29 | uses: actions/setup-python@v5 30 | with: 31 | python-version: ${{ matrix.python-version }} 32 | - name: Install dependencies 33 | run: | 34 | sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 x11-utils 35 | /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX 36 | python -m pip install --upgrade pip 37 | python -m pip install ruff pytest 38 | pip install PyQt5 39 | pip install . 40 | - name: Lint with Ruff 41 | run: ruff check --output-format=github cdl 42 | - name: Test with pytest 43 | run: pytest -v --tb=long 44 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [FORMAT] 2 | # Essential to be able to compare code side-by-side (`black` default setting) 3 | # and best compromise to minimize file size 4 | max-line-length=88 5 | 6 | [TYPECHECK] 7 | ignored-modules=qtpy.QtWidgets,qtpy.QtCore,qtpy.QtGui,cv2,plotpy._scaler,skimage.restoration,skimage.feature 8 | 9 | [MESSAGES CONTROL] 10 | disable=wrong-import-order 11 | 12 | [DESIGN] 13 | max-args=10 # default: 5 14 | max-attributes=12 # default: 7 15 | max-branches=20 # default: 12 16 | max-locals=20 # default: 15 17 | min-public-methods=0 # default: 2 18 | max-public-methods=25 # default: 20 -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for Sphinx projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | version: 2 5 | build: 6 | os: ubuntu-22.04 7 | tools: 8 | python: "3.11" 9 | sphinx: 10 | configuration: doc/conf.py 11 | formats: 12 | - pdf 13 | python: 14 | install: 15 | - method: pip 16 | path: . 17 | extra_requirements: 18 | - doc 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[bat]": { 3 | "files.encoding": "cp850", 4 | }, 5 | "editor.rulers": [ 6 | 88 7 | ], 8 | "files.exclude": { 9 | "**/__pycache__": true, 10 | "**/*.pyc": true, 11 | "**/*.pyo": true 12 | }, 13 | "files.trimFinalNewlines": true, 14 | "files.trimTrailingWhitespace": true, 15 | "python.defaultInterpreterPath": "${env:CDL_PYTHONEXE}", 16 | "editor.formatOnSave": true, 17 | "python.analysis.autoFormatStrings": true, 18 | "python.testing.unittestEnabled": false, 19 | "python.testing.pytestEnabled": true, 20 | "python.testing.pytestPath": "pytest", 21 | "python.testing.pytestArgs": [], 22 | "[python]": { 23 | "editor.defaultFormatter": "charliermarsh.ruff" 24 | }, 25 | "editor.codeActionsOnSave": { 26 | "source.organizeImports": "explicit", 27 | }, 28 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | DataLab is **your** platform. If you want it to be improved, you **can** contribute to 4 | the project, whether you are a developer or not. 5 | 6 | There are many ways to contribute to DataLab project, depending on how much time you 7 | have, your experience with open source projects, and your skills. 8 | 9 | To get started, please refer to our [contributing documentation](https://datalab-platform.com/en/contributing/index.html) for detailed instructions on how to contribute to the project. 10 | 11 | Happy contributing! 12 | -------------------------------------------------------------------------------- /DataLab-demo.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | for %%a in ("%CDL_PYTHONEXE%") do set "p_dir=%%~dpa" 3 | for %%a in (%p_dir:~0,-1%) do set "WINPYDIRBASE=%%~dpa" 4 | call %WINPYDIRBASE%scripts\env_for_icons.bat %* 5 | cd/D %~dp0 6 | set PYTHONPATH=%cd% 7 | start "" "%WINPYDIR%\pythonw.exe" -m cdl.tests.scenarios.demo %* -------------------------------------------------------------------------------- /DataLab.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | for %%a in ("%CDL_PYTHONEXE%") do set "p_dir=%%~dpa" 3 | for %%a in (%p_dir:~0,-1%) do set "WINPYDIRBASE=%%~dpa" 4 | call %WINPYDIRBASE%scripts\env_for_icons.bat %* 5 | cd/D %~dp0 6 | set ORIGINAL_PYTHONPATH=%PYTHONPATH% 7 | for /F "tokens=*" %%A in (.env) do (set %%A) 8 | set PYTHONPATH=%PYTHONPATH%;%ORIGINAL_PYTHONPATH% 9 | start "" "%WINPYDIR%\pythonw.exe" cdl\start.pyw %* -------------------------------------------------------------------------------- /DataLab.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Name=cdl 5 | GenericName=DataLab 6 | Comment=Run DataLab, the Python Signal and image processing software 7 | TryExec=cdl 8 | Exec=cdl 9 | Icon=DataLab.svg 10 | Categories=Education;Science;Physics; 11 | -------------------------------------------------------------------------------- /DataLab.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | # Initial command: 4 | # pyinstaller -y --clean -n DataLab -i resources\DataLab.ico cdl\start.pyw 5 | 6 | from PyInstaller.utils.hooks import collect_submodules, collect_data_files 7 | all_hidden_imports = collect_submodules('cdl') 8 | datas = collect_data_files('cdl') + [('cdl\\plugins', 'cdl\\plugins')] 9 | datas += collect_data_files('guidata') + collect_data_files('plotpy') 10 | 11 | a = Analysis( 12 | ['cdl\\start.pyw'], 13 | pathex=[], 14 | binaries=[], 15 | datas=datas, 16 | hiddenimports=all_hidden_imports, 17 | hookspath=[], 18 | hooksconfig={}, 19 | runtime_hooks=[], 20 | excludes=[], 21 | noarchive=False, 22 | ) 23 | pyz = PYZ(a.pure) 24 | 25 | exe = EXE( 26 | pyz, 27 | a.scripts, 28 | [], 29 | exclude_binaries=True, 30 | name='DataLab', 31 | debug=False, 32 | bootloader_ignore_signals=False, 33 | strip=False, 34 | upx=True, 35 | console=False, 36 | disable_windowed_traceback=False, 37 | argv_emulation=False, 38 | target_arch=None, 39 | codesign_identity=None, 40 | entitlements_file=None, 41 | icon=['resources\\DataLab.ico'], 42 | ) 43 | coll = COLLECT( 44 | exe, 45 | a.binaries, 46 | a.datas, 47 | strip=False, 48 | upx=True, 49 | upx_exclude=[], 50 | name='DataLab', 51 | ) 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, DataLab Platform Developers. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft doc 2 | graft resources 3 | graft macros 4 | graft plugins 5 | include conftest.py 6 | include CHANGELOG.md 7 | include CONTRIBUTING.md 8 | include requirements.txt 9 | include *.desktop -------------------------------------------------------------------------------- /cdl/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | DataLab 5 | ======= 6 | 7 | DataLab is a generic signal and image processing software based on Python 8 | scientific libraries (such as NumPy, SciPy or scikit-image) and Qt graphical 9 | user interfaces (thanks to `PlotPyStack`_ libraries). 10 | 11 | .. _PlotPyStack: https://github.com/PlotPyStack 12 | """ 13 | 14 | import os 15 | 16 | __version__ = "0.20.0" 17 | __docurl__ = __homeurl__ = "https://datalab-platform.com/" 18 | __supporturl__ = "https://github.com/DataLab-Platform/DataLab/issues/new/choose" 19 | 20 | os.environ["CDL_VERSION"] = __version__ 21 | 22 | # Dear (Debian, RPM, ...) package makers, please feel free to customize the 23 | # following path to module's data (images) and translations: 24 | DATAPATH = LOCALEPATH = "" 25 | -------------------------------------------------------------------------------- /cdl/algorithms/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Algorithms (:mod:`cdl.algorithms`) 3 | ---------------------------------- 4 | 5 | This package contains the algorithms used by the DataLab project. Those algorithms 6 | operate directly on NumPy arrays and are designed to be used in the DataLab pipeline, 7 | but can be used independently as well. 8 | 9 | .. seealso:: 10 | 11 | The :mod:`cdl.algorithms` package is the main entry point for the DataLab 12 | algorithms when manipulating NumPy arrays. See the :mod:`cdl.computation` 13 | package for algorithms that operate directly on DataLab objects (i.e. 14 | :class:`cdl.obj.SignalObj` and :class:`cdl.obj.ImageObj`). 15 | 16 | The algorithms are organized in subpackages according to their purpose. The following 17 | subpackages are available: 18 | 19 | - :mod:`cdl.algorithms.signal`: Signal processing algorithms 20 | - :mod:`cdl.algorithms.image`: Image processing algorithms 21 | - :mod:`cdl.algorithms.datatypes`: Data type conversion algorithms 22 | - :mod:`cdl.algorithms.coordinates`: Coordinate conversion algorithms 23 | 24 | Signal Processing Algorithms 25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 26 | 27 | .. automodule:: cdl.algorithms.signal 28 | :members: 29 | 30 | Image Processing Algorithms 31 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 32 | 33 | .. automodule:: cdl.algorithms.image 34 | :members: 35 | 36 | Data Type Conversion Algorithms 37 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 38 | 39 | .. automodule:: cdl.algorithms.datatypes 40 | :members: 41 | 42 | Coordinate Conversion Algorithms 43 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 44 | 45 | .. automodule:: cdl.algorithms.coordinates 46 | :members: 47 | 48 | """ 49 | -------------------------------------------------------------------------------- /cdl/algorithms/datatypes.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | .. Data Type Conversion Algorithms (see parent package :mod:`cdl.algorithms`) 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | 9 | from __future__ import annotations 10 | 11 | import numpy as np 12 | 13 | 14 | def is_integer_dtype(dtype: np.dtype) -> bool: 15 | """Return True if data type is an integer type 16 | 17 | Args: 18 | dtype: Data type to check 19 | 20 | Returns: 21 | True if data type is an integer type 22 | """ 23 | return issubclass(np.dtype(dtype).type, np.integer) 24 | 25 | 26 | def is_complex_dtype(dtype: np.dtype) -> bool: 27 | """Return True if data type is a complex type 28 | 29 | Args: 30 | dtype: Data type to check 31 | 32 | Returns: 33 | True if data type is a complex type 34 | """ 35 | return issubclass(np.dtype(dtype).type, complex) 36 | 37 | 38 | def clip_astype(data: np.ndarray, dtype: np.dtype) -> np.ndarray: 39 | """Convert array to a new data type, after having clipped values to the new 40 | data type's range if it is an integer type. 41 | If data type is not integer, this is equivalent to ``data.astype(dtype)``. 42 | 43 | Args: 44 | data: Array to convert 45 | dtype: Data type to convert to 46 | 47 | Returns: 48 | Array converted to new data type 49 | """ 50 | if is_integer_dtype(dtype): 51 | return np.clip(data, np.iinfo(dtype).min, np.iinfo(dtype).max).astype(dtype) 52 | return data.astype(dtype) 53 | -------------------------------------------------------------------------------- /cdl/core/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/core/gui/panel/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Panel 3 | ===== 4 | 5 | The :mod:`cdl.core.gui.panel` package provides the **panel objects** 6 | for signals and images. 7 | 8 | Three types of panels are available: 9 | 10 | - :class:`cdl.core.gui.panel.signal.SignalPanel`: Signal panel 11 | - :class:`cdl.core.gui.panel.image.ImagePanel`: Image panel 12 | - :class:`cdl.core.gui.panel.macro.MacroPanel`: Macro panel 13 | 14 | Signal and Image Panels are called **Data Panels** and are used to display and 15 | handle signals and images in the main window of DataLab. 16 | 17 | Data Panels rely on the :class:`cdl.core.gui.panel.base.ObjectProp` class (managing 18 | the object properties) and a set of modules to handle the GUI features: 19 | 20 | - :mod:`cdl.core.gui.actionhandler`: Application actions (menus, toolbars, context menu) 21 | - :mod:`cdl.core.gui.objectview`: Widgets to display object (signal/image) trees 22 | - :mod:`cdl.core.gui.plothandler`: `PlotPy` items for representing signals and images 23 | - :mod:`cdl.core.gui.processor`: Processor (computation) 24 | - :mod:`cdl.core.gui.panel.roieditor`: ROI editor 25 | 26 | The Macro Panel is used to display and run macros. It relies on the 27 | :mod:`cdl.core.gui.macroeditor` module to handle the macro edition and execution. 28 | 29 | Base features 30 | ------------- 31 | 32 | .. automodule:: cdl.core.gui.panel.base 33 | 34 | Signal panel 35 | ------------ 36 | 37 | .. automodule:: cdl.core.gui.panel.signal 38 | 39 | Image panel 40 | ----------- 41 | 42 | .. automodule:: cdl.core.gui.panel.image 43 | 44 | Macro panel 45 | ----------- 46 | 47 | .. automodule:: cdl.core.gui.panel.macro 48 | """ 49 | -------------------------------------------------------------------------------- /cdl/core/gui/processor/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Processor 3 | ========= 4 | 5 | The :mod:`cdl.core.gui.processor` package provides the **processor objects** 6 | for signals and images. 7 | 8 | Processor objects are the bridge between the computation modules 9 | (in :mod:`cdl.computation`) and the GUI modules (in :mod:`cdl.core.gui`). 10 | They are used to call the computation functions and to update the GUI from inside 11 | the data panel objects. 12 | 13 | When implementing a processing feature in DataLab, the steps are usually the following: 14 | 15 | - Add an action in the :mod:`cdl.core.gui.actionhandler` module to trigger the 16 | processing feature from the GUI (e.g. a menu item or a toolbar button). 17 | 18 | - Implement the computation function in the :mod:`cdl.computation` module 19 | (that would eventually call the algorithm from the :mod:`cdl.algorithms` module). 20 | 21 | - Implement the processor object method in this package to call the computation 22 | function and eventually update the GUI. 23 | 24 | The processor objects are organized in submodules according to their purpose. 25 | 26 | The following submodules are available: 27 | 28 | - :mod:`cdl.core.gui.processor.base`: Common processing features 29 | - :mod:`cdl.core.gui.processor.signal`: Signal processing features 30 | - :mod:`cdl.core.gui.processor.image`: Image processing features 31 | 32 | Common features 33 | --------------- 34 | 35 | .. automodule:: cdl.core.gui.processor.base 36 | 37 | Signal processing features 38 | -------------------------- 39 | 40 | .. automodule:: cdl.core.gui.processor.signal 41 | 42 | Image processing features 43 | ------------------------- 44 | 45 | .. automodule:: cdl.core.gui.processor.image 46 | """ 47 | -------------------------------------------------------------------------------- /cdl/core/io/h5/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | 4 | """ 5 | DataLab HDF5 importer module 6 | """ 7 | 8 | # pylint: disable=unused-import 9 | 10 | # Registering dynamic I/O features: 11 | from cdl.core.io.h5 import generic # noqa: F401 12 | from cdl.core.io.h5.common import H5Importer # noqa: F401 13 | -------------------------------------------------------------------------------- /cdl/core/io/image/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | DataLab image I/O features 5 | """ 6 | 7 | # pylint: disable=unused-import 8 | import cdl.core.io.image.formats # noqa: F401 9 | from cdl.core.io.image.base import ImageIORegistry # noqa: F401 10 | -------------------------------------------------------------------------------- /cdl/core/io/native.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | DataLab Native I/O module (native HDF5/JSON formats) 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | 9 | from __future__ import annotations 10 | 11 | from guidata.io import HDF5Reader, HDF5Writer 12 | 13 | import cdl 14 | 15 | DATALAB_VERSION_NAME = "DataLab_Version" 16 | 17 | 18 | class NativeH5Writer(HDF5Writer): 19 | """DataLab signal/image objects HDF5 guidata Dataset Writer class 20 | 21 | Args: 22 | filename (str): HDF5 file name 23 | """ 24 | 25 | def __init__(self, filename: str) -> None: 26 | super().__init__(filename) 27 | self.h5[DATALAB_VERSION_NAME] = cdl.__version__ 28 | 29 | 30 | class NativeH5Reader(HDF5Reader): 31 | """DataLab signal/image objects HDF5 guidata dataset Writer class 32 | 33 | Args: 34 | filename (str): HDF5 file name 35 | """ 36 | 37 | def __init__(self, filename: str) -> None: 38 | super().__init__(filename) 39 | self.version = self.h5[DATALAB_VERSION_NAME] 40 | -------------------------------------------------------------------------------- /cdl/core/io/signal/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | DataLab signal I/O features 5 | """ 6 | 7 | # pylint: disable=unused-import 8 | import cdl.core.io.signal.formats # noqa: F401 9 | from cdl.core.io.signal.base import SignalIORegistry # noqa: F401 10 | -------------------------------------------------------------------------------- /cdl/core/model/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/data/dependencies-py3-win32.txt: -------------------------------------------------------------------------------- 1 | guidata:5e43ccd551157ba777611c77cfa6597656644699 2 | plotpy:c44704fba1fc898f944d9b1ab9c86f02fed3a7a9 3 | -------------------------------------------------------------------------------- /cdl/data/icons/apply.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /cdl/data/icons/h5/h5scalar.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-camera-flash-off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-camera-flash-on.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-about.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-action-delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-arrow-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-arrow-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-arrow-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-help.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-pencil.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-plugin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-questions.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-gui-unlink.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-tech-ram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/libre-toolbox.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/logs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/play_demo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/processing/stability.svg: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /cdl/data/icons/reset.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cdl/data/icons/restore.svg: -------------------------------------------------------------------------------- 1 | 2 | 41 | -------------------------------------------------------------------------------- /cdl/data/icons/tour/stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 48 | -------------------------------------------------------------------------------- /cdl/data/logo/DataLab-Banner-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/logo/DataLab-Banner-150.png -------------------------------------------------------------------------------- /cdl/data/logo/DataLab-Banner-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/logo/DataLab-Banner-200.png -------------------------------------------------------------------------------- /cdl/data/logo/DataLab-Banner2-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/logo/DataLab-Banner2-100.png -------------------------------------------------------------------------------- /cdl/data/logo/DataLab-Splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/logo/DataLab-Splash.png -------------------------------------------------------------------------------- /cdl/data/logo/DataLab-watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/logo/DataLab-watermark.png -------------------------------------------------------------------------------- /cdl/data/tests/curve_formats/noised_saw.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/curve_formats/noised_saw.mat -------------------------------------------------------------------------------- /cdl/data/tests/curve_formats/other/other2/recursive2.txt: -------------------------------------------------------------------------------- 1 | 1850.0 -0.443 2 | 1851.0 -0.288 3 | 1852.0 -0.289 4 | 1853.0 -0.333 5 | 1854.0 -0.304 -------------------------------------------------------------------------------- /cdl/data/tests/curve_formats/other/recursive1.txt: -------------------------------------------------------------------------------- 1 | 1850.0 -0.443 2 | 1851.0 -0.288 3 | 1852.0 -0.289 4 | 1853.0 -0.333 5 | 1854.0 -0.304 -------------------------------------------------------------------------------- /cdl/data/tests/curve_formats/paracetamol.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/curve_formats/paracetamol.npy -------------------------------------------------------------------------------- /cdl/data/tests/curve_formats/simple.txt: -------------------------------------------------------------------------------- 1 | 1850.0 -0.443 2 | 1851.0 -0.288 3 | 1852.0 -0.289 4 | 1853.0 -0.333 5 | 1854.0 -0.304 -------------------------------------------------------------------------------- /cdl/data/tests/empty.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/empty.h5 -------------------------------------------------------------------------------- /cdl/data/tests/fabry-perot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/fabry-perot1.jpg -------------------------------------------------------------------------------- /cdl/data/tests/fabry-perot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/fabry-perot2.jpg -------------------------------------------------------------------------------- /cdl/data/tests/flower.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/flower.npy -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/NF 180338201.scor-data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/NF 180338201.scor-data -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/binary_image.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/binary_image.npy -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/binary_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/binary_image.png -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/fiber.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/fiber.bmp -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/fiber.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/fiber.jpg -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/fiber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/fiber.png -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/mr-brain.dcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/mr-brain.dcm -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/noised_gaussian.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/noised_gaussian.mat -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/sif_reader/nd_lum_image_no_glue.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/sif_reader/nd_lum_image_no_glue.sif -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/sif_reader/raman1.sif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/sif_reader/raman1.sif -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/uint16.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/uint16.tiff -------------------------------------------------------------------------------- /cdl/data/tests/image_formats/uint8.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/image_formats/uint8.tiff -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_13.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_18.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_23.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_30.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_35.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_40.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_45.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_50.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_55.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_60.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_65.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_70.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_70.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_75.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_75.jpg -------------------------------------------------------------------------------- /cdl/data/tests/laser_beam/TEM00_z_80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/laser_beam/TEM00_z_80.jpg -------------------------------------------------------------------------------- /cdl/data/tests/reordering_test.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/cdl/data/tests/reordering_test.h5 -------------------------------------------------------------------------------- /cdl/plugins/_readme_.txt: -------------------------------------------------------------------------------- 1 | Warning: 2 | -------- 3 | 4 | This folder is not a Python package. 5 | That is intentional, because it is not meant to be imported. 6 | It is distributed as data folder from a packaging point of view. 7 | 8 | It contains a collection of plugins that are automatically loaded by the 9 | plugin system. -------------------------------------------------------------------------------- /cdl/tests/backbone/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/backbone/memory_leak.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Memory leak test 5 | 6 | DataLab application memory leak test. 7 | """ 8 | 9 | # guitest: skip 10 | 11 | import os 12 | 13 | import numpy as np 14 | import psutil 15 | from guidata.qthelpers import qt_app_context 16 | 17 | from cdl.env import execenv 18 | from cdl.tests.features.control.embedded1_unit_test import HostWindow 19 | from cdl.utils.vistools import view_curves 20 | 21 | 22 | def memory_leak_test(iterations=100): 23 | """Test for memory leak""" 24 | with qt_app_context(): 25 | proc = psutil.Process(os.getpid()) 26 | mainview = HostWindow() 27 | mainview.show() 28 | memlist = [] 29 | for i in range(iterations): 30 | mainview.init_cdl() 31 | mainview.close_cdl() 32 | memdata = proc.memory_info().vms / 1024**2 33 | memlist.append(memdata) 34 | execenv.print(i + 1, ":", memdata, "MB") 35 | view_curves( 36 | np.array(memlist), 37 | title="Memory leak test for DataLab application", 38 | ylabel="Memory (MB)", 39 | ) 40 | 41 | 42 | if __name__ == "__main__": 43 | memory_leak_test() 44 | -------------------------------------------------------------------------------- /cdl/tests/backbone/procisolation_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Process isolation unit test 5 | --------------------------- 6 | 7 | Just test if it's possible to run the process isolation test from another module. This 8 | may be an issue with the Pool object being global. 9 | """ 10 | 11 | # guitest: show 12 | 13 | from cdl.tests.backbone import procisolation1_unit 14 | 15 | 16 | def test_procisolation(): 17 | """Test process isolation""" 18 | procisolation1_unit.test_multiprocessing1() 19 | 20 | 21 | if __name__ == "__main__": 22 | test_procisolation() 23 | -------------------------------------------------------------------------------- /cdl/tests/backbone/profiling_app.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Profiling 5 | """ 6 | 7 | # guitest: skip 8 | 9 | from cdl.env import execenv 10 | from cdl.tests import cdltest_app_context 11 | 12 | 13 | def test_profiling(): 14 | """Profiling test""" 15 | with execenv.context(unattended=True): 16 | with cdltest_app_context() as win: 17 | win.open_h5_files( 18 | [ 19 | "C:/Dev/Projets/X-GRID_data/Projets_Oasis/XGRID5/" 20 | "VS000001-blobs_doh_profiling.h5" 21 | ], 22 | import_all=True, 23 | ) 24 | 25 | 26 | if __name__ == "__main__": 27 | test_profiling() 28 | -------------------------------------------------------------------------------- /cdl/tests/features/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/applauncher/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/applauncher/launcher1_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Basic application launcher test 1 5 | 6 | Running application a few times in a row with different entry parameters. 7 | """ 8 | 9 | # guitest: show 10 | 11 | from cdl import app 12 | from cdl.env import execenv 13 | from cdl.utils.qthelpers import cdl_app_context 14 | 15 | 16 | def test_launcher1(screenshots: bool = False): 17 | """Testing DataLab app launcher""" 18 | with cdl_app_context(exec_loop=not screenshots): 19 | execenv.print("Opening DataLab with no argument") 20 | win = app.create() 21 | if screenshots: 22 | win.statusBar().hide() 23 | win.take_screenshot("s_app_at_startup") 24 | win.close() 25 | 26 | 27 | if __name__ == "__main__": 28 | test_launcher1() 29 | -------------------------------------------------------------------------------- /cdl/tests/features/applauncher/launcher2_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Basic application launcher test 2 5 | 6 | Create signal and image objects (with circles, rectangles, segments and markers), 7 | then open DataLab to show them. 8 | """ 9 | 10 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 11 | # guitest: show 12 | 13 | import cdl.obj 14 | from cdl.app import run 15 | from cdl.tests import data as test_data 16 | 17 | 18 | def test_launcher2(): 19 | """Simple test""" 20 | sig1 = test_data.create_paracetamol_signal() 21 | sig2 = test_data.create_noisy_signal() 22 | param = cdl.obj.new_image_param(height=2000, width=2000) 23 | ima1 = test_data.create_sincos_image(param) 24 | ima2 = test_data.create_noisygauss_image(param, add_annotations=True) 25 | run(objects=(sig1, sig2, ima1, ima2), size=(1200, 550)) 26 | 27 | 28 | if __name__ == "__main__": 29 | test_launcher2() 30 | -------------------------------------------------------------------------------- /cdl/tests/features/common/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/common/arithmeticparam_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Arithmetic parameters unit test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | from guidata.qthelpers import qt_app_context 11 | 12 | from cdl.env import execenv 13 | from cdl.param import ArithmeticParam 14 | 15 | 16 | def test_arithmetic_param_interactive(): 17 | """Arithmetic parameters interactive test.""" 18 | with qt_app_context(): 19 | param = ArithmeticParam() 20 | if param.edit(): 21 | execenv.print(param) 22 | 23 | 24 | if __name__ == "__main__": 25 | test_arithmetic_param_interactive() 26 | -------------------------------------------------------------------------------- /cdl/tests/features/common/resultproperties_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Result properties application test 5 | """ 6 | 7 | # guitest: show 8 | 9 | from __future__ import annotations 10 | 11 | import numpy as np 12 | 13 | from cdl.tests import cdltest_app_context 14 | from cdl.tests import data as test_data 15 | 16 | 17 | def create_image_with_resultproperties(): 18 | """Create test image with result properties""" 19 | image = test_data.create_multigauss_image() 20 | for prop in test_data.create_resultproperties(): 21 | prop.add_to(image) 22 | return image 23 | 24 | 25 | def test_resultproperties(): 26 | """Result properties application test""" 27 | obj1 = test_data.create_sincos_image() 28 | obj2 = create_image_with_resultproperties() 29 | with cdltest_app_context(console=False) as win: 30 | panel = win.signalpanel 31 | noiseparam = test_data.GaussianNoiseParam() 32 | for sigma in np.linspace(0.0, 0.5, 11): 33 | noiseparam.sigma = sigma 34 | sig = test_data.create_noisy_signal(noiseparam=noiseparam) 35 | panel.add_object(sig) 36 | panel.processor.compute_dynamic_parameters() 37 | panel.processor.compute_contrast() 38 | panel.objview.selectAll() 39 | panel.show_results() 40 | panel.plot_results() 41 | win.set_current_panel("image") 42 | panel = win.imagepanel 43 | for obj in (obj1, obj2): 44 | panel.add_object(obj) 45 | panel.show_results() 46 | panel.plot_results() 47 | 48 | 49 | if __name__ == "__main__": 50 | test_resultproperties() 51 | -------------------------------------------------------------------------------- /cdl/tests/features/common/stat_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Statistics test 5 | 6 | Testing the following: 7 | - Create a signal 8 | - Compute statistics on signal and show results 9 | - Create an image 10 | - Compute statistics on image and show results 11 | """ 12 | 13 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 14 | # guitest: show 15 | 16 | from cdl.tests import cdltest_app_context, take_plotwidget_screenshot 17 | from cdl.tests.features.common.stat_unit_test import ( 18 | create_reference_image, 19 | create_reference_signal, 20 | ) 21 | 22 | 23 | def test_stat_app(): 24 | """Run statistics application test scenario""" 25 | with cdltest_app_context() as win: 26 | # === Signal statistics test === 27 | panel = win.signalpanel 28 | panel.add_object(create_reference_signal()) 29 | take_plotwidget_screenshot(panel, "stat_test") 30 | panel.processor.compute_stats() 31 | # === Image statistics test === 32 | panel = win.imagepanel 33 | panel.add_object(create_reference_image()) 34 | take_plotwidget_screenshot(panel, "stat_test") 35 | panel.processor.compute_stats() 36 | 37 | 38 | if __name__ == "__main__": 39 | test_stat_app() 40 | -------------------------------------------------------------------------------- /cdl/tests/features/control/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/control/connect_dialog.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | DataLab Remote client connection dialog example 5 | """ 6 | 7 | # guitest: show,skip 8 | 9 | from guidata.qthelpers import qt_app_context 10 | from qtpy import QtWidgets as QW 11 | 12 | from cdl.proxy import RemoteProxy 13 | from cdl.widgets.connection import ConnectionDialog 14 | 15 | 16 | def test_dialog(): 17 | """Test connection dialog""" 18 | proxy = RemoteProxy(autoconnect=False) 19 | with qt_app_context(): 20 | dlg = ConnectionDialog(proxy.connect) 21 | if dlg.exec(): 22 | QW.QMessageBox.information(None, "Connection", "Successfully connected") 23 | else: 24 | QW.QMessageBox.critical(None, "Connection", "Connection failed") 25 | 26 | 27 | if __name__ == "__main__": 28 | test_dialog() 29 | -------------------------------------------------------------------------------- /cdl/tests/features/control/embedded2_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Application embedded test 2 5 | 6 | DataLab main window is simply hidden when closing application. 7 | It is shown and raised above other windows when reopening application. 8 | """ 9 | 10 | # guitest: show 11 | 12 | from cdl.core.gui.main import CDLMainWindow 13 | from cdl.tests.features.control import embedded1_unit_test 14 | 15 | 16 | class HostWindow(embedded1_unit_test.AbstractHostWindow): 17 | """Test main view""" 18 | 19 | def init_cdl(self) -> None: 20 | """Open DataLab test""" 21 | if self.cdl is None: 22 | self.cdl = CDLMainWindow(console=False, hide_on_close=True) 23 | self.host.log("✨ Initialized DataLab window") 24 | self.cdl.show() 25 | else: 26 | self.cdl.show() 27 | self.cdl.raise_window() 28 | self.host.log("=> Shown DataLab window") 29 | 30 | def close_cdl(self) -> None: 31 | """Close DataLab window""" 32 | if self.cdl is not None: 33 | self.host.log("=> Closed DataLab") 34 | self.cdl.close() 35 | 36 | def closeEvent(self, event) -> None: # pylint: disable=invalid-name 37 | """Close event 38 | 39 | Reimplemented from QWidget.closeEvent""" 40 | if self.cdl is None or self.cdl.close_properly(): 41 | event.accept() 42 | else: 43 | event.ignore() 44 | 45 | 46 | def test_embedded_feature(): 47 | """Testing embedded feature""" 48 | embedded1_unit_test.run_host_window(HostWindow) 49 | 50 | 51 | if __name__ == "__main__": 52 | test_embedded_feature() 53 | -------------------------------------------------------------------------------- /cdl/tests/features/hdf5/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/hdf5/h5browser1_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | HDF5 browser unit tests 1 5 | ------------------------- 6 | 7 | Try and open all HDF5 test data available. 8 | """ 9 | 10 | # guitest: show 11 | 12 | from __future__ import annotations 13 | 14 | from guidata.qthelpers import exec_dialog, qt_app_context 15 | 16 | from cdl.tests.data import get_test_fnames 17 | from cdl.tests.features.hdf5.h5browser_app_test import create_h5browser_dialog 18 | 19 | 20 | def test_h5browser_all_files(pattern=None): 21 | """HDF5 browser unit test for all available .h5 test files""" 22 | with qt_app_context(): 23 | fnames = get_test_fnames("*.h5" if pattern is None else pattern) 24 | for index, fname in enumerate(fnames): 25 | dlg = create_h5browser_dialog([fname], toggle_all=True, select_all=True) 26 | dlg.setObjectName(dlg.objectName() + f"_{index:02d}") 27 | exec_dialog(dlg) 28 | 29 | 30 | if __name__ == "__main__": 31 | test_h5browser_all_files() 32 | -------------------------------------------------------------------------------- /cdl/tests/features/hdf5/h5importer_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | HDF5 Importer Application test 5 | ------------------------------ 6 | 7 | Running application a few times in a row with different entry parameters. 8 | """ 9 | 10 | # guitest: show 11 | 12 | from cdl import app 13 | from cdl.env import execenv 14 | from cdl.utils.qthelpers import cdl_app_context 15 | from cdl.utils.tests import get_test_fnames 16 | 17 | 18 | def test_h5importer_app(pattern=None): 19 | """Testing DataLab app launcher""" 20 | if pattern is None: 21 | pattern = "*.h5" 22 | execenv.print("HDF5 import test scenario:") 23 | execenv.print("[1] Loading all h5 files at once (only the first 5 files)") 24 | with cdl_app_context(exec_loop=True): 25 | app.create(h5files=get_test_fnames(pattern)[:5]) 26 | execenv.print("[2] Loading h5 files one by one") 27 | for fname in get_test_fnames(pattern): 28 | with cdl_app_context(exec_loop=True): 29 | execenv.print(f" Opening: {fname}") 30 | app.create(h5files=[fname]) 31 | 32 | 33 | if __name__ == "__main__": 34 | test_h5importer_app() 35 | -------------------------------------------------------------------------------- /cdl/tests/features/images/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/images/annotations_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Annotations application test: 5 | 6 | - Create an image with annotations and ROI 7 | - Further tests to be done manually: edit "Annotations" and check that 8 | modifications are taken into account, without affecting the existing ROI 9 | """ 10 | 11 | # guitest: show 12 | 13 | from cdl.app import run 14 | from cdl.obj import create_image_roi 15 | from cdl.tests import data as test_data 16 | 17 | 18 | def test_annotations_app(): 19 | """Annotations test""" 20 | obj1 = test_data.create_sincos_image() 21 | obj2 = test_data.create_annotated_image() 22 | obj2.roi = create_image_roi("rectangle", [10, 10, 60, 400]) 23 | run(console=False, objects=(obj1, obj2), size=(1200, 550)) 24 | 25 | 26 | if __name__ == "__main__": 27 | test_annotations_app() 28 | -------------------------------------------------------------------------------- /cdl/tests/features/images/blobs_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Blob detection application test 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import cdl.param 11 | from cdl.obj import create_image 12 | from cdl.tests import cdltest_app_context 13 | from cdl.tests.data import get_test_image 14 | 15 | 16 | def test_blobs(): 17 | """Run blob detection application test scenario""" 18 | with cdltest_app_context() as win: 19 | panel = win.imagepanel 20 | proc = panel.processor 21 | data = get_test_image("flower.npy").data 22 | 23 | # Testing blob detection 24 | # ====================== 25 | for paramclass, compute_method, name in ( 26 | (cdl.param.BlobDOGParam, proc.compute_blob_dog, "BlobDOG"), 27 | (cdl.param.BlobDOHParam, proc.compute_blob_doh, "BlobDOH"), 28 | (cdl.param.BlobLOGParam, proc.compute_blob_log, "BlobLOG"), 29 | (cdl.param.BlobOpenCVParam, proc.compute_blob_opencv, "BlobOpenCV"), 30 | ): 31 | param = paramclass() 32 | image = create_image(name, data) 33 | image.add_label_with_title() 34 | panel.add_object(image) 35 | compute_method(param) 36 | 37 | # Testing distribute_on_grid and reset_positions 38 | # ============================================== 39 | panel.objview.selectAll() 40 | param = cdl.param.GridParam.create(cols=2, colspac=10, rowspac=10) 41 | proc.distribute_on_grid(param) 42 | 43 | 44 | if __name__ == "__main__": 45 | test_blobs() 46 | -------------------------------------------------------------------------------- /cdl/tests/features/images/contour_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Contour finding application test 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import cdl.obj 11 | import cdl.param 12 | from cdl.env import execenv 13 | from cdl.tests import cdltest_app_context, take_plotwidget_screenshot 14 | from cdl.tests.data import create_multigauss_image 15 | from cdl.tests.features.common.roi_app_test import create_test_image_with_roi 16 | 17 | 18 | def test_contour_app(): 19 | """Run contour finding application test scenario""" 20 | newparam = cdl.obj.new_image_param(height=200, width=200) 21 | with cdltest_app_context() as win: 22 | panel = win.imagepanel 23 | for shape in ("polygon", "circle", "ellipse"): 24 | ima1 = create_multigauss_image(newparam) 25 | ima1.metadata["colormap"] = "gray" 26 | panel.add_object(ima1) 27 | param = cdl.param.ContourShapeParam.create(shape=shape) 28 | panel.processor.compute_contour_shape(param) 29 | take_plotwidget_screenshot(panel, "contour_test") 30 | ima2 = create_test_image_with_roi(newparam) 31 | ima2.metadata["colormap"] = "gray" 32 | panel.add_object(ima2) 33 | panel.processor.edit_regions_of_interest() 34 | panel.processor.compute_contour_shape(param) 35 | if not execenv.unattended: 36 | break 37 | 38 | 39 | if __name__ == "__main__": 40 | test_contour_app() 41 | -------------------------------------------------------------------------------- /cdl/tests/features/images/denoise_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Denoise processing application test 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import cdl.param 11 | from cdl.tests import cdltest_app_context 12 | from cdl.tests.data import get_test_image 13 | 14 | 15 | def test_denoise(): 16 | """Run denoise application test scenario""" 17 | with cdltest_app_context() as win: 18 | win.showMaximized() 19 | panel = win.imagepanel 20 | panel.add_object(get_test_image("flower.npy")) 21 | proc = panel.processor 22 | proc.compute_all_denoise() 23 | panel.objview.select_groups() 24 | param = cdl.param.GridParam.create(cols=3) 25 | proc.distribute_on_grid(param) 26 | panel.add_label_with_title() 27 | 28 | 29 | if __name__ == "__main__": 30 | test_denoise() 31 | -------------------------------------------------------------------------------- /cdl/tests/features/images/edges_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Edges processing application test 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import cdl.param 11 | from cdl.tests import cdltest_app_context 12 | from cdl.tests.data import get_test_image 13 | 14 | 15 | def test_edges(): 16 | """Run edges processing application test scenario""" 17 | with cdltest_app_context() as win: 18 | win.showMaximized() 19 | panel = win.imagepanel 20 | panel.add_object(get_test_image("flower.npy")) 21 | proc = panel.processor 22 | proc.compute_all_edges() 23 | panel.objview.select_groups() 24 | param = cdl.param.GridParam.create(cols=4) 25 | proc.distribute_on_grid(param) 26 | panel.add_label_with_title() 27 | 28 | 29 | if __name__ == "__main__": 30 | test_edges() 31 | -------------------------------------------------------------------------------- /cdl/tests/features/images/fft2d_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image FFT application test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | from cdl.obj import ImageTypes, create_image_from_param, new_image_param 11 | from cdl.tests import cdltest_app_context 12 | 13 | 14 | def test_fft2d_app(): 15 | """FFT application test.""" 16 | with cdltest_app_context() as win: 17 | panel = win.imagepanel 18 | newparam = new_image_param(itype=ImageTypes.GAUSS, width=100, height=100) 19 | i1 = create_image_from_param(newparam) 20 | panel.add_object(i1) 21 | panel.processor.compute_fft() 22 | panel.processor.compute_ifft() 23 | 24 | 25 | if __name__ == "__main__": 26 | test_fft2d_app() 27 | -------------------------------------------------------------------------------- /cdl/tests/features/images/flatfield_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Flat field test 5 | 6 | Testing the following: 7 | - Create a gaussian image (raw data) 8 | - Create a random noised image (flat data) 9 | - Compute the flat field image 10 | """ 11 | 12 | # guitest: show 13 | 14 | from cdl.config import _ 15 | from cdl.obj import Gauss2DParam, ImageTypes, UniformRandomParam, new_image_param 16 | from cdl.param import FlatFieldParam 17 | from cdl.tests import cdltest_app_context 18 | 19 | 20 | def test_flatfield(): 21 | """Run flat field test scenario""" 22 | with cdltest_app_context() as win: 23 | panel = win.imagepanel 24 | 25 | ima0 = panel.new_object( 26 | new_image_param(_("Raw data (2D-Gaussian)"), itype=ImageTypes.GAUSS), 27 | addparam=Gauss2DParam(), 28 | edit=False, 29 | ) 30 | addp = UniformRandomParam() 31 | addp.vmax = 5 32 | ima1 = panel.new_object( 33 | new_image_param( 34 | _("Flat data (Uniform random)"), itype=ImageTypes.UNIFORMRANDOM 35 | ), 36 | addparam=addp, 37 | edit=False, 38 | ) 39 | 40 | panel.objview.select_objects([ima0]) 41 | ffp = FlatFieldParam() 42 | ffp.threshold = 80 43 | panel.processor.compute_flatfield(ima1, ffp) 44 | 45 | 46 | if __name__ == "__main__": 47 | test_flatfield() 48 | -------------------------------------------------------------------------------- /cdl/tests/features/images/imagetools_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image tools test 5 | 6 | Simple image dialog for testing all image tools available in DataLab 7 | """ 8 | 9 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 10 | # guitest: show 11 | 12 | from guidata.qthelpers import qt_app_context 13 | from plotpy.builder import make 14 | 15 | from cdl.tests.data import create_noisygauss_image 16 | from cdl.utils.vistools import view_image_items 17 | 18 | 19 | def test_image_tools_unit(): 20 | """Image tools test""" 21 | with qt_app_context(): 22 | data = create_noisygauss_image().data 23 | items = [make.image(data, interpolation="nearest", eliminate_outliers=2.0)] 24 | view_image_items(items) 25 | 26 | 27 | if __name__ == "__main__": 28 | test_image_tools_unit() 29 | -------------------------------------------------------------------------------- /cdl/tests/features/images/morph_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Morphology processing application test 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import cdl.param 11 | from cdl.tests import cdltest_app_context 12 | from cdl.tests.data import get_test_image 13 | 14 | 15 | def test_morphology(): 16 | """Run morphology application test scenario""" 17 | with cdltest_app_context() as win: 18 | win.showMaximized() 19 | panel = win.imagepanel 20 | panel.add_object(get_test_image("flower.npy")) 21 | proc = panel.processor 22 | param = cdl.param.MorphologyParam.create(radius=10) 23 | proc.compute_all_morphology(param) 24 | panel.objview.select_groups() 25 | param = cdl.param.GridParam.create(cols=4) 26 | proc.distribute_on_grid(param) 27 | panel.add_label_with_title() 28 | 29 | 30 | if __name__ == "__main__": 31 | test_morphology() 32 | -------------------------------------------------------------------------------- /cdl/tests/features/images/peak2d_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | 2D peak detection test 5 | 6 | Testing the following: 7 | - Create a test image with multiple peaks 8 | - Compute 2D peak detection and show points on image 9 | """ 10 | 11 | # guitest: show 12 | 13 | import cdl.param 14 | from cdl.tests import cdltest_app_context, take_plotwidget_screenshot 15 | from cdl.tests.data import create_peak2d_image 16 | 17 | 18 | def test_peak2d(): 19 | """Run 2D peak detection scenario""" 20 | with cdltest_app_context() as win: 21 | panel = win.imagepanel 22 | ima = create_peak2d_image() 23 | panel.add_object(ima) 24 | param = cdl.param.Peak2DDetectionParam.create(create_rois=True) 25 | panel.processor.compute_peak_detection(param) 26 | win.toggle_show_titles(False) 27 | take_plotwidget_screenshot(panel, "peak2d_test") 28 | 29 | 30 | if __name__ == "__main__": 31 | test_peak2d() 32 | -------------------------------------------------------------------------------- /cdl/tests/features/images/peak2d_limits_unit.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image peak detection test: testing algorithm limits 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: skip 9 | 10 | from guidata.qthelpers import qt_app_context 11 | 12 | from cdl.algorithms.image import get_2d_peaks_coords 13 | from cdl.env import execenv 14 | from cdl.tests.data import get_peak2d_data 15 | from cdl.tests.features.images.peak2d_unit_test import exec_image_peak_detection_func 16 | 17 | 18 | def peak2d_limit_test(): 19 | """2D peak detection test""" 20 | with qt_app_context(): 21 | execenv.print("Testing peak detection algorithm with random generated data:") 22 | for idx in range(100): 23 | execenv.print(f" Iteration #{idx:02d}: ", end="") 24 | generated_data = get_peak2d_data(multi=True) 25 | coords = get_2d_peaks_coords(generated_data) 26 | if coords.shape[0] != 4: 27 | execenv.print(f"KO - {coords.shape[0]}/4 peaks were detected") 28 | exec_image_peak_detection_func(generated_data) 29 | else: 30 | execenv.print("OK") 31 | # Showing results for last generated sample 32 | exec_image_peak_detection_func(generated_data) 33 | 34 | 35 | if __name__ == "__main__": 36 | peak2d_limit_test() 37 | -------------------------------------------------------------------------------- /cdl/tests/features/images/peak2d_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image peak detection test 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # pylint: disable=duplicate-code 9 | # guitest: show 10 | 11 | import time 12 | 13 | from guidata.qthelpers import qt_app_context 14 | from plotpy.builder import make 15 | 16 | from cdl.algorithms.image import get_2d_peaks_coords 17 | from cdl.env import execenv 18 | from cdl.tests.data import get_peak2d_data 19 | from cdl.utils.vistools import view_image_items 20 | 21 | 22 | def exec_image_peak_detection_func(data): 23 | """Compare image peak detection methods""" 24 | items = [make.image(data, interpolation="linear", colormap="hsv")] 25 | t0 = time.time() 26 | coords = get_2d_peaks_coords(data) 27 | dt = time.time() - t0 28 | for x, y in coords: 29 | items.append(make.marker((x, y))) 30 | execenv.print(f"Calculation time: {int(dt * 1e3):d} ms") 31 | execenv.print(f" => {coords.tolist()}") 32 | view_image_items(items) 33 | 34 | 35 | def test_peak2d_unit(): 36 | """2D peak detection test""" 37 | with qt_app_context(): 38 | exec_image_peak_detection_func(get_peak2d_data(multi=False)) 39 | 40 | 41 | if __name__ == "__main__": 42 | test_peak2d_unit() 43 | -------------------------------------------------------------------------------- /cdl/tests/features/images/roi2dparam_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | ROI image parameters unit test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import guidata.dataset as gds 11 | import numpy as np 12 | from guidata.qthelpers import qt_app_context 13 | 14 | from cdl.core.model.image import ROI2DParam 15 | from cdl.env import execenv 16 | 17 | 18 | def test_roi_param_interactive(): 19 | """ROI parameters interactive test.""" 20 | with qt_app_context(): 21 | p_circ = ROI2DParam("Circular") 22 | p_circ.geometry = "circle" 23 | p_circ.xc, p_circ.yc, p_circ.r = 100, 200, 50 24 | p_rect = ROI2DParam("Rectangular") 25 | p_rect.geometry = "rectangle" 26 | p_rect.x0, p_rect.y0, p_rect.dx, p_rect.dy = 50, 150, 150, 250 27 | p_poly = ROI2DParam("Polygonal") 28 | p_poly.geometry = "polygon" 29 | p_poly.points = np.array([[50, 150], [150, 150], [150, 250], [50, 250]]) 30 | params = [p_circ, p_rect, p_poly] 31 | group = gds.DataSetGroup(params, title="ROI Parameters") 32 | if group.edit(): 33 | for param in params: 34 | execenv.print(param) 35 | 36 | 37 | if __name__ == "__main__": 38 | test_roi_param_interactive() 39 | -------------------------------------------------------------------------------- /cdl/tests/features/images/select_background_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image background selection unit test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import numpy as np 11 | from guidata.qthelpers import exec_dialog, qt_app_context 12 | 13 | from cdl.env import execenv 14 | from cdl.tests.data import create_noisygauss_image 15 | from cdl.widgets.imagebackground import ImageBackgroundDialog 16 | 17 | 18 | def test_image_background_selection(): 19 | """Image background selection test.""" 20 | with qt_app_context(): 21 | img = create_noisygauss_image() 22 | dlg = ImageBackgroundDialog(img) 23 | dlg.resize(640, 480) 24 | dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix 25 | with execenv.context(delay=200): 26 | # For more details about the why of the delay, see the comment in 27 | # cdl\tests\features\image\offset_correction_unit_test.py 28 | exec_dialog(dlg) 29 | execenv.print(f"background: {dlg.get_background()}") 30 | execenv.print(f"rect coords: {dlg.get_rect_coords()}") 31 | # Check background value: 32 | x0, y0, x1, y1 = dlg.get_rect_coords() 33 | ix0, iy0, ix1, iy1 = dlg.imageitem.get_closest_index_rect(x0, y0, x1, y1) 34 | assert np.isclose(img.data[iy0:iy1, ix0:ix1].mean(), dlg.get_background()) 35 | 36 | 37 | if __name__ == "__main__": 38 | test_image_background_selection() 39 | -------------------------------------------------------------------------------- /cdl/tests/features/images/spectrum2d_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image spectrum unit test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # pylint: disable=duplicate-code 9 | # guitest: show 10 | 11 | from guidata.qthelpers import qt_app_context 12 | 13 | import cdl.algorithms.image as alg 14 | from cdl.tests.data import get_test_image 15 | from cdl.utils.vistools import view_images_side_by_side 16 | 17 | 18 | def test_image_spectrum_interactive(): 19 | """Interactive test of the magnitude/phase/power spectrum of an image.""" 20 | with qt_app_context(): 21 | obj = get_test_image("NF 180338201.scor-data") 22 | data = obj.data 23 | ms = alg.magnitude_spectrum(data, log_scale=True) 24 | ps = alg.phase_spectrum(data) 25 | psd = alg.psd(data, log_scale=True) 26 | images = [data, ms, ps, psd] 27 | titles = [ 28 | "Original", 29 | "Magnitude spectrum", 30 | "Phase spectrum", 31 | "Power spectral density", 32 | ] 33 | view_images_side_by_side(images, titles, rows=2, title="Image spectrum") 34 | 35 | 36 | if __name__ == "__main__": 37 | test_image_spectrum_interactive() 38 | -------------------------------------------------------------------------------- /cdl/tests/features/macro/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/macro/macro_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Macro Panel application test 5 | (essentially for the screenshot...) 6 | """ 7 | 8 | # guitest: show 9 | 10 | from cdl import config 11 | from cdl.core.gui.main import CDLMainWindow 12 | from cdl.utils import qthelpers as qth 13 | 14 | 15 | def test_macro(screenshots: bool = False) -> None: 16 | """Run image tools test scenario""" 17 | config.reset() # Reset configuration (remove configuration file and initialize it) 18 | with qth.cdl_app_context(exec_loop=True): 19 | win = CDLMainWindow() 20 | win.show() 21 | win.set_current_panel("macro") 22 | win.macropanel.add_macro() 23 | if screenshots: 24 | qth.grab_save_window(win.macropanel, "macro_panel") 25 | 26 | 27 | if __name__ == "__main__": 28 | test_macro() 29 | -------------------------------------------------------------------------------- /cdl/tests/features/signals/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/signals/deltax_dialog_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Signal delta x dialog unit test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | from guidata.qthelpers import exec_dialog, qt_app_context 11 | 12 | from cdl.algorithms.signal import full_width_at_y 13 | from cdl.tests.data import create_paracetamol_signal 14 | from cdl.widgets.signaldeltax import SignalDeltaXDialog 15 | 16 | 17 | def test_signal_delta_x_dialog(): 18 | """Test the SignalDeltaXDialog widget.""" 19 | sig = create_paracetamol_signal() 20 | with qt_app_context(): 21 | dlg = SignalDeltaXDialog(signal=sig) 22 | dlg.resize(640, 480) 23 | dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix 24 | exec_dialog(dlg) 25 | y = dlg.get_y_value() 26 | x0, y0, x1, y1 = dlg.get_coords() 27 | exp_x0, exp_y0, exp_x1, exp_y1 = full_width_at_y((sig.x, sig.y), y) 28 | assert (x0, y0, x1, y1) == (exp_x0, exp_y0, exp_x1, exp_y1), ( 29 | f"Expected: {(exp_x0, exp_y0, exp_x1, exp_y1)} " f"but got: {(x0, y0, x1, y1)}" 30 | ) 31 | 32 | 33 | if __name__ == "__main__": 34 | test_signal_delta_x_dialog() 35 | -------------------------------------------------------------------------------- /cdl/tests/features/signals/fft1d_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Signal FFT application test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | from cdl.obj import SignalTypes, create_signal_from_param, new_signal_param 11 | from cdl.tests import cdltest_app_context 12 | 13 | 14 | def test_fft1d_app(): 15 | """FFT application test.""" 16 | with cdltest_app_context() as win: 17 | panel = win.signalpanel 18 | newparam = new_signal_param(stype=SignalTypes.COSINUS, size=10000) 19 | s1 = create_signal_from_param(newparam) 20 | panel.add_object(s1) 21 | panel.processor.compute_fft() 22 | panel.processor.compute_ifft() 23 | 24 | 25 | if __name__ == "__main__": 26 | test_fft1d_app() 27 | -------------------------------------------------------------------------------- /cdl/tests/features/signals/peak1d_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Signal peak detection test 5 | 6 | Testing peak detection dialog box. 7 | """ 8 | 9 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 10 | # guitest: show 11 | 12 | from guidata.qthelpers import exec_dialog, qt_app_context 13 | 14 | from cdl.env import execenv 15 | from cdl.tests.data import get_test_signal 16 | from cdl.widgets.signalpeak import SignalPeakDetectionDialog 17 | 18 | 19 | def test_peak1d(): 20 | """Signal peak dialog test""" 21 | with qt_app_context(): 22 | s = get_test_signal("paracetamol.txt") 23 | dlg = SignalPeakDetectionDialog(s) 24 | dlg.resize(640, 300) 25 | plot = dlg.get_plot() 26 | plot.set_axis_limits(plot.xBottom, 16, 30) 27 | dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix 28 | exec_dialog(dlg) 29 | execenv.print("peaks:") 30 | execenv.pprint(dlg.get_peaks()) 31 | execenv.pprint(dlg.get_min_dist()) 32 | 33 | 34 | if __name__ == "__main__": 35 | test_peak1d() 36 | -------------------------------------------------------------------------------- /cdl/tests/features/signals/select_baseline_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Signal base line selection unit test. 5 | """ 6 | 7 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 8 | # guitest: show 9 | 10 | import numpy as np 11 | from guidata.qthelpers import exec_dialog, qt_app_context 12 | 13 | from cdl.env import execenv 14 | from cdl.tests.data import create_paracetamol_signal 15 | from cdl.widgets.signalbaseline import SignalBaselineDialog 16 | 17 | 18 | def test_signal_baseline_selection(): 19 | """Signal baseline selection dialog test""" 20 | sig = create_paracetamol_signal() 21 | with qt_app_context(): 22 | dlg = SignalBaselineDialog(sig) 23 | dlg.resize(640, 480) 24 | dlg.setObjectName(dlg.objectName() + "_00") # to avoid timestamp suffix 25 | exec_dialog(dlg) 26 | execenv.print(f"baseline: {dlg.get_baseline()}") 27 | execenv.print(f"X range: {dlg.get_x_range()}") 28 | # Check baseline value: 29 | i0, i1 = np.searchsorted(sig.x, dlg.get_x_range()) 30 | assert dlg.get_baseline() == sig.data[i0:i1].mean() 31 | 32 | 33 | if __name__ == "__main__": 34 | test_signal_baseline_selection() 35 | -------------------------------------------------------------------------------- /cdl/tests/features/tour_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Tour test 5 | """ 6 | 7 | # guitest: show 8 | 9 | from cdl.core.gui.tour import start 10 | from cdl.tests import cdltest_app_context 11 | 12 | 13 | def test_tour() -> None: 14 | """ 15 | Test the tour of DataLab features. 16 | """ 17 | with cdltest_app_context() as win: 18 | start(win) 19 | 20 | 21 | if __name__ == "__main__": 22 | test_tour() 23 | -------------------------------------------------------------------------------- /cdl/tests/features/utilities/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/features/utilities/installconf_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Dependencies viewer test 5 | """ 6 | 7 | # guitest: show 8 | 9 | from __future__ import annotations 10 | 11 | from guidata.qthelpers import qt_app_context 12 | 13 | import cdl.utils.qthelpers as qth 14 | from cdl.widgets import instconfviewer 15 | 16 | 17 | def test_dep_viewer(screenshots: bool = False) -> None: 18 | """Test dep viewer window""" 19 | with qt_app_context(): 20 | instconfviewer.exec_cdl_installconfig_dialog() 21 | if screenshots: 22 | dlg = instconfviewer.InstallConfigViewerWindow() 23 | dlg.show() 24 | qth.grab_save_window(dlg, dlg.objectName()) 25 | 26 | 27 | if __name__ == "__main__": 28 | test_dep_viewer(screenshots=True) 29 | -------------------------------------------------------------------------------- /cdl/tests/features/utilities/logview_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Log viewer test 5 | """ 6 | 7 | # guitest: show 8 | 9 | from cdl.app import run 10 | from cdl.tests.features.utilities import logview_error 11 | from cdl.utils.tests import exec_script 12 | 13 | 14 | def test_logviewer_app(): 15 | """Test log viewer""" 16 | exec_script(logview_error.__file__) 17 | run() 18 | 19 | 20 | if __name__ == "__main__": 21 | test_logviewer_app() 22 | -------------------------------------------------------------------------------- /cdl/tests/features/utilities/logview_error.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Log viewer test: raise an exception and create a seg fault in DataLab 5 | """ 6 | 7 | # guitest: skip 8 | 9 | from guidata.qthelpers import qt_app_context 10 | 11 | from cdl.core.gui.main import CDLMainWindow 12 | from cdl.env import execenv 13 | 14 | 15 | def error(): 16 | """Raise an exception and create a seg fault in DataLab""" 17 | with execenv.context(unattended=True): 18 | with qt_app_context(exec_loop=True): 19 | win = CDLMainWindow() 20 | win.test_segfault_error() 21 | 22 | 23 | if __name__ == "__main__": 24 | error() 25 | -------------------------------------------------------------------------------- /cdl/tests/features/utilities/logview_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Log viewer test 5 | """ 6 | 7 | # guitest: show 8 | 9 | from guidata.qthelpers import qt_app_context 10 | 11 | from cdl.widgets.logviewer import exec_cdl_logviewer_dialog 12 | 13 | 14 | def test_logviewer_dialog(): 15 | """Test log viewer window""" 16 | with qt_app_context(): 17 | exec_cdl_logviewer_dialog() 18 | 19 | 20 | if __name__ == "__main__": 21 | test_logviewer_dialog() 22 | -------------------------------------------------------------------------------- /cdl/tests/features/utilities/memstatus_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Memory status widget application test 5 | """ 6 | 7 | # guitest: show 8 | 9 | import numpy as np 10 | import psutil 11 | 12 | from cdl import config 13 | from cdl.env import execenv 14 | from cdl.obj import Gauss2DParam, ImageTypes, new_image_param 15 | from cdl.tests import cdltest_app_context 16 | 17 | 18 | def memory_alarm(threshold): 19 | """Memory alarm test""" 20 | config.Conf.main.available_memory_threshold.set(threshold) 21 | rng = np.random.default_rng() 22 | with cdltest_app_context() as win: 23 | panel = win.imagepanel 24 | win.memorystatus.update_status() # Force memory status update 25 | newparam = new_image_param(itype=ImageTypes.GAUSS) 26 | addparam = Gauss2DParam.create( 27 | x0=rng.integers(-9, 9), y0=rng.integers(-9, 9), sigma=rng.integers(1, 20) 28 | ) 29 | panel.new_object(newparam, addparam=addparam, edit=False) 30 | 31 | 32 | def test_mem_status(): 33 | """Memory alarm test""" 34 | mem_available = psutil.virtual_memory().available // (1024**2) 35 | execenv.print(f"Memory status widget test (memory available: {mem_available} MB):") 36 | for index, threshold in enumerate((mem_available * 2, mem_available - 100)): 37 | execenv.print(f" Threshold {index}: {threshold} MB") 38 | memory_alarm(threshold) 39 | config.reset() 40 | 41 | 42 | if __name__ == "__main__": 43 | test_mem_status() 44 | -------------------------------------------------------------------------------- /cdl/tests/features/utilities/settings_unit_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | DataLab settings test 5 | """ 6 | 7 | # guitest: show 8 | 9 | from guidata.qthelpers import qt_app_context 10 | 11 | from cdl.core.gui.settings import edit_settings 12 | from cdl.env import execenv 13 | 14 | 15 | def test_edit_settings(): 16 | """Test edit settings""" 17 | with qt_app_context(): 18 | changed = edit_settings(None) 19 | execenv.print(changed) 20 | 21 | 22 | if __name__ == "__main__": 23 | test_edit_settings() 24 | -------------------------------------------------------------------------------- /cdl/tests/scenarios/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/tests/scenarios/example_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Example of high-level test scenario 5 | 6 | Create an image object from Scikit-image human mitosis sample, 7 | then open DataLab to show it. 8 | """ 9 | 10 | # pylint: disable=invalid-name # Allows short reference names like x, y, ... 11 | # guitest: show 12 | 13 | import cdl.obj as dlo 14 | import cdl.param as dlp 15 | from cdl.proxy import proxy_context 16 | from cdl.tests.data import get_test_image 17 | 18 | 19 | def test_example_app(): 20 | """Example of high-level test scenario using proxy interface, so that it may 21 | be run remotely inside an already running DataLab instance, or in a new 22 | dedicated instance.""" 23 | with proxy_context("local") as proxy: 24 | data = get_test_image("flower.npy").data 25 | image = dlo.create_image("Test image with peaks", data) 26 | proxy.add_object(image) 27 | proxy.compute_roberts() 28 | data_size = data.shape[0] 29 | n = data_size // 5 30 | roi = dlo.create_image_roi( 31 | "rectangle", [n, n, data_size - 2 * n, data_size - 2 * n] 32 | ) 33 | proxy.compute_roi_extraction(roi) 34 | param = dlp.BlobOpenCVParam.create( 35 | min_dist_between_blobs=0.1, 36 | filter_by_color=False, 37 | min_area=500, 38 | max_area=2000, 39 | filter_by_circularity=True, 40 | min_circularity=0.2, 41 | ) 42 | proxy.compute_blob_opencv(param) 43 | 44 | 45 | if __name__ == "__main__": 46 | test_example_app() 47 | -------------------------------------------------------------------------------- /cdl/tests/scenarios/scenario_ima1_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image processing test scenario 5 | ------------------------------ 6 | 7 | Testing all the image processing features, without process isolation. 8 | """ 9 | 10 | # pylint: disable=duplicate-code 11 | # guitest: show 12 | 13 | from cdl.config import Conf 14 | from cdl.env import execenv 15 | from cdl.tests import cdltest_app_context 16 | from cdl.tests.scenarios import common 17 | 18 | 19 | def test_scenario_image() -> None: 20 | """Run image unit test scenario 1 (no process isolation)""" 21 | assert ( 22 | Conf.main.process_isolation_enabled.get() 23 | ), "Process isolation must be enabled" 24 | with cdltest_app_context(save=True) as win: 25 | with win.context_no_refresh(): 26 | execenv.print("Testing image features without process isolation...") 27 | win.set_process_isolation_enabled(False) 28 | common.run_image_computations(win) 29 | win.imagepanel.remove_all_objects() 30 | execenv.print("==> OK") 31 | 32 | 33 | if __name__ == "__main__": 34 | test_scenario_image() 35 | -------------------------------------------------------------------------------- /cdl/tests/scenarios/scenario_ima2_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Image processing test scenario 5 | ------------------------------ 6 | 7 | Testing all the image processing features, with process isolation. 8 | """ 9 | 10 | # pylint: disable=duplicate-code 11 | # guitest: show 12 | 13 | from cdl.config import Conf 14 | from cdl.env import execenv 15 | from cdl.tests import cdltest_app_context 16 | from cdl.tests.scenarios import common 17 | 18 | 19 | def test_scenario_image2() -> None: 20 | """Run image unit test scenario 2 (process isolation)""" 21 | assert ( 22 | Conf.main.process_isolation_enabled.get() 23 | ), "Process isolation must be enabled" 24 | 25 | with cdltest_app_context(save=True) as win: 26 | execenv.print("Testing image features *with* process isolation...") 27 | common.run_image_computations(win, all_types=False) 28 | oids = win.imagepanel.objmodel.get_object_ids() 29 | win.imagepanel.open_separate_view(oids[:4]) 30 | execenv.print("==> OK") 31 | 32 | 33 | if __name__ == "__main__": 34 | test_scenario_image2() 35 | -------------------------------------------------------------------------------- /cdl/tests/scenarios/scenario_sig1_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Signal processing test scenario 5 | ------------------------------- 6 | 7 | Testing all the signal processing features, without process isolation. 8 | """ 9 | 10 | # pylint: disable=duplicate-code 11 | # guitest: show 12 | 13 | from __future__ import annotations 14 | 15 | from cdl.config import Conf 16 | from cdl.env import execenv 17 | from cdl.tests import cdltest_app_context 18 | from cdl.tests.scenarios import common 19 | 20 | 21 | def test_scenario_signal1() -> None: 22 | """Run signal unit test scenario 1 (no process isolation)""" 23 | assert ( 24 | Conf.main.process_isolation_enabled.get() 25 | ), "Process isolation must be enabled" 26 | with cdltest_app_context(save=True) as win: 27 | with win.context_no_refresh(): 28 | execenv.print("Testing signal features (process isolation: off)...") 29 | win.set_process_isolation_enabled(False) 30 | common.run_signal_computations(win, all_types=True) 31 | win.signalpanel.remove_all_objects() 32 | execenv.print("==> OK") 33 | 34 | 35 | if __name__ == "__main__": 36 | test_scenario_signal1() 37 | -------------------------------------------------------------------------------- /cdl/tests/scenarios/scenario_sig2_app_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Signal processing test scenario 5 | ------------------------------- 6 | 7 | Testing all the signal processing features, with process isolation. 8 | """ 9 | 10 | # pylint: disable=duplicate-code 11 | # guitest: show 12 | 13 | from __future__ import annotations 14 | 15 | from cdl.config import Conf 16 | from cdl.env import execenv 17 | from cdl.tests import cdltest_app_context 18 | from cdl.tests.scenarios import common 19 | 20 | 21 | def test_scenario_signal2() -> None: 22 | """Run signal unit test scenario 2 (process isolation)""" 23 | assert ( 24 | Conf.main.process_isolation_enabled.get() 25 | ), "Process isolation must be enabled" 26 | with cdltest_app_context(save=True) as win: 27 | execenv.print("Testing signal features (process isolation: on)...") 28 | common.run_signal_computations(win, all_types=False) 29 | oids = win.signalpanel.objmodel.get_object_ids() 30 | win.signalpanel.open_separate_view(oids[:3]) 31 | execenv.print("==> OK") 32 | 33 | 34 | if __name__ == "__main__": 35 | test_scenario_signal2() 36 | -------------------------------------------------------------------------------- /cdl/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /cdl/utils/io.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | DataLab I/O utilities 5 | """ 6 | 7 | from __future__ import annotations 8 | 9 | from itertools import islice 10 | 11 | 12 | def count_lines(filename: str) -> int: 13 | """Count the number of lines in a file 14 | 15 | Args: 16 | filename: File name 17 | 18 | Returns: 19 | The number of lines in the file 20 | """ 21 | for encoding in ("utf-8", "utf-8-sig", "latin-1"): 22 | try: 23 | with open(filename, "r", encoding=encoding) as file: 24 | line_count = sum(1 for line in file) 25 | return line_count 26 | except UnicodeDecodeError: 27 | pass 28 | raise IOError(f"Cannot read file {filename}") 29 | 30 | 31 | def read_first_n_lines(filename: str, n: int = 100000) -> str: 32 | """Read the first n lines of a file 33 | 34 | Args: 35 | filename: File name 36 | n: Number of lines to read 37 | 38 | Returns: 39 | The first n lines of the file 40 | """ 41 | for encoding in ("utf-8", "utf-8-sig", "latin-1"): 42 | try: 43 | with open(filename, "r", encoding=encoding) as file: 44 | lines = list(islice(file, n)) 45 | return "".join(lines) 46 | except UnicodeDecodeError: 47 | pass 48 | raise IOError(f"Cannot read file {filename}") 49 | -------------------------------------------------------------------------------- /cdl/widgets/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /create_dephash.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. 2 | 3 | """ 4 | Create dependencies hash 5 | """ 6 | 7 | from cdl.config import DATAPATH 8 | from cdl.utils import dephash 9 | 10 | dephash.create_dependencies_file(DATAPATH, ("guidata", "plotpy")) 11 | -------------------------------------------------------------------------------- /doc/_static/DataLab-Frontpage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/doc/_static/DataLab-Frontpage.png -------------------------------------------------------------------------------- /doc/_static/DataLab-Title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/doc/_static/DataLab-Title.png -------------------------------------------------------------------------------- /doc/_static/codra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/doc/_static/codra.png -------------------------------------------------------------------------------- /doc/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/doc/_static/favicon.ico -------------------------------------------------------------------------------- /doc/_static/plotpy-stack-powered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataLab-Platform/DataLab/269de0614e9155127b998b798ad080092f3bee84/doc/_static/plotpy-stack-powered.png -------------------------------------------------------------------------------- /doc/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | 3 | {% block htmltitle %} 4 | 5 | 6 | 13 | {% if pagename == 'index' %} 14 |