pymodaq 4.4.7__py3-none-any.whl → 5.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +57 -91
- pymodaq/control_modules/daq_move.py +64 -46
- pymodaq/control_modules/daq_move_ui.py +34 -12
- pymodaq/control_modules/daq_viewer.py +55 -30
- pymodaq/control_modules/daq_viewer_ui.py +6 -6
- pymodaq/control_modules/mocks.py +1 -1
- pymodaq/control_modules/move_utility_classes.py +51 -43
- pymodaq/control_modules/utils.py +43 -20
- pymodaq/control_modules/viewer_utility_classes.py +54 -18
- pymodaq/daq_utils/daq_utils.py +6 -0
- pymodaq/dashboard.py +639 -323
- pymodaq/examples/function_plotter.py +13 -12
- pymodaq/examples/tcp_client.py +1 -1
- pymodaq/extensions/__init__.py +1 -1
- pymodaq/extensions/bayesian/bayesian_optimisation.py +44 -32
- pymodaq/extensions/bayesian/utils.py +10 -10
- pymodaq/extensions/console.py +7 -6
- pymodaq/extensions/daq_logger/__init__.py +1 -0
- pymodaq/extensions/{daq_logger.py → daq_logger/daq_logger.py} +30 -30
- pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger.py +16 -15
- pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger_models.py +2 -0
- pymodaq/{utils/h5modules → extensions/daq_logger}/h5logging.py +7 -8
- pymodaq/extensions/daq_scan.py +42 -34
- pymodaq/extensions/daq_scan_ui.py +18 -18
- pymodaq/extensions/h5browser.py +2 -3
- pymodaq/extensions/pid/__init__.py +4 -2
- pymodaq/extensions/pid/daq_move_PID.py +3 -3
- pymodaq/extensions/pid/pid_controller.py +59 -50
- pymodaq/extensions/pid/utils.py +10 -5
- pymodaq/extensions/utils.py +33 -3
- pymodaq/post_treatment/load_and_plot.py +10 -7
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/updater.py +107 -0
- pymodaq/utils/array_manipulation.py +4 -384
- pymodaq/utils/calibration_camera.py +12 -9
- pymodaq/utils/chrono_timer.py +11 -10
- pymodaq/utils/config.py +3 -458
- pymodaq/utils/daq_utils.py +9 -715
- pymodaq/utils/data.py +17 -2959
- pymodaq/utils/enums.py +4 -74
- pymodaq/utils/exceptions.py +0 -4
- pymodaq/utils/gui_utils/__init__.py +8 -8
- pymodaq/utils/gui_utils/loader_utils.py +26 -1
- pymodaq/utils/gui_utils/utils.py +8 -162
- pymodaq/utils/gui_utils/widgets/lcd.py +6 -109
- pymodaq/utils/h5modules/__init__.py +0 -4
- pymodaq/utils/h5modules/module_saving.py +9 -8
- pymodaq/utils/leco/__init__.py +2 -2
- pymodaq/utils/leco/daq_move_LECODirector.py +3 -6
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +5 -5
- pymodaq/utils/leco/director_utils.py +2 -2
- pymodaq/utils/leco/leco_director.py +3 -3
- pymodaq/utils/leco/pymodaq_listener.py +4 -3
- pymodaq/utils/leco/utils.py +11 -9
- pymodaq/utils/logger.py +4 -76
- pymodaq/utils/managers/batchscan_manager.py +16 -19
- pymodaq/utils/managers/modules_manager.py +30 -17
- pymodaq/utils/managers/overshoot_manager.py +48 -6
- pymodaq/utils/managers/preset_manager.py +39 -59
- pymodaq/utils/managers/preset_manager_utils.py +28 -22
- pymodaq/utils/managers/remote_manager.py +12 -10
- pymodaq/utils/math_utils.py +4 -582
- pymodaq/utils/messenger.py +4 -64
- pymodaq/utils/parameter/__init__.py +6 -9
- pymodaq/utils/parameter/utils.py +4 -328
- pymodaq/utils/scanner/scan_config.py +1 -1
- pymodaq/utils/scanner/scan_factory.py +16 -12
- pymodaq/utils/{plotting → scanner}/scan_selector.py +19 -20
- pymodaq/utils/scanner/scanner.py +10 -8
- pymodaq/utils/scanner/scanners/_1d_scanners.py +8 -5
- pymodaq/utils/scanner/scanners/_2d_scanners.py +5 -5
- pymodaq/utils/scanner/scanners/sequential.py +8 -8
- pymodaq/utils/scanner/scanners/tabular.py +9 -9
- pymodaq/utils/scanner/utils.py +6 -4
- pymodaq/utils/svg/svg_viewer2D.py +3 -4
- pymodaq/utils/tcp_ip/mysocket.py +4 -110
- pymodaq/utils/tcp_ip/serializer.py +4 -801
- pymodaq/utils/tcp_ip/tcp_server_client.py +15 -13
- pymodaq-5.0.1.dist-info/METADATA +242 -0
- pymodaq-5.0.1.dist-info/RECORD +122 -0
- {pymodaq-4.4.7.dist-info → pymodaq-5.0.1.dist-info}/WHEEL +1 -1
- {pymodaq-4.4.7.dist-info → pymodaq-5.0.1.dist-info}/entry_points.txt +1 -0
- pymodaq/examples/custom_app.py +0 -258
- pymodaq/examples/custom_viewer.py +0 -112
- pymodaq/examples/parameter_ex.py +0 -138
- pymodaq/examples/preset_MockCamera.xml +0 -1
- pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py +0 -142
- pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui +0 -232
- pymodaq/post_treatment/daq_measurement/daq_measurement_main.py +0 -391
- pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -2
- pymodaq/post_treatment/process_to_scalar.py +0 -263
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/1d.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/2d.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/3d.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add_Step.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve_All.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Browse_Dir_Path.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Calculator.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnGroup.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnNum.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnText.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnTime.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnWave.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Close3.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ColorPicker.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Contract.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Create.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/DeleteLayer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditOpen.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditRedo.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditUndo.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Ellipse.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EllipseFilled.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ErrorMessage.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Exit.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Expand.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/FFT.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/HLM.ico +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Histogram.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/LUT_LookUpTable.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass_24.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Marker.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Math.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MeasurementStudio_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Move.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveDown.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveUp.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Multiply.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewFile.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewLayer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_File.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_Folder.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_1D.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_2D.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_sim.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Options.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Pass.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/RGB.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rectangle.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/RectangleFilled.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Redo.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Region.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rendezvous.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SELECT.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_24.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Search.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SelectPolygon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Select_24.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Settings.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snap&Save.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Spreadsheet.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Status.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Subtract.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Vision.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Volts.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Wait2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_1_1.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_in.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_out.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_to_Selection.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/abort.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/advanced2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/algo.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/autoscale.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/b_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/back.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/bg_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera_snap.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/cartesian.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear_ROI.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/close2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/cluster2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/color.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/color2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/continuous.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/data.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/delay.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/download.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/download2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/error2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ethernet.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/exit2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/fan.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/filter2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/g_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/gear2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_1.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/grab.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/graph.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/green_light.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/grey_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/greyscale.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/home2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/information2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ini.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/input.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/integrator.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/joystick.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/limiter.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/load_ROI.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meshPlot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_contour.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_straight_line.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/movie.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/multi_point.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/multiplexer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/new.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/openArrow.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/openTree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope3.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/overlay.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pause.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/permute.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/phase.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/play.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/polar.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pole_zero.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerMeter.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/properties.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/r_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/radiocontrolbutton.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/random.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/read2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/red_light.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/remove.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/reset.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/rgb_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/robot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/rotation2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/saturation.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/saveTree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/save_ROI.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_horizontally.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_vertically.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/search2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_none.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/snap.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sort_ascend.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/spectrumAnalyzer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/start.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/status_cancelled.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop3.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sum.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/surfacePlot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/target.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/tree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/updateTree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility_small.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/vector.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/verify.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/video.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/wait.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/waterfallPlot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/watershed.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/yellow_light.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/zip_file.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomAuto.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomReset.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +0 -2
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +0 -238
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +0 -127453
- pymodaq/resources/QtDesigner_Ressources/__init__.py +0 -0
- pymodaq/resources/QtDesigner_Ressources/credit.rst +0 -7
- pymodaq/resources/QtDesigner_Ressources/icons.svg +0 -142
- pymodaq/resources/VERSION +0 -2
- pymodaq/resources/config_template.toml +0 -96
- pymodaq/resources/triangulation_data.npy +0 -0
- pymodaq/utils/abstract/__init__.py +0 -48
- pymodaq/utils/db/__init__.py +0 -0
- pymodaq/utils/db/db_logger/__init__.py +0 -0
- pymodaq/utils/factory.py +0 -82
- pymodaq/utils/gui_utils/custom_app.py +0 -133
- pymodaq/utils/gui_utils/dock.py +0 -107
- pymodaq/utils/gui_utils/file_io.py +0 -94
- pymodaq/utils/gui_utils/layout.py +0 -34
- pymodaq/utils/gui_utils/list_picker.py +0 -38
- pymodaq/utils/gui_utils/widgets/__init__.py +0 -5
- pymodaq/utils/gui_utils/widgets/label.py +0 -24
- pymodaq/utils/gui_utils/widgets/push.py +0 -149
- pymodaq/utils/gui_utils/widgets/qled.py +0 -62
- pymodaq/utils/gui_utils/widgets/spinbox.py +0 -24
- pymodaq/utils/gui_utils/widgets/table.py +0 -263
- pymodaq/utils/gui_utils/widgets/tree_layout.py +0 -188
- pymodaq/utils/gui_utils/widgets/tree_toml.py +0 -110
- pymodaq/utils/h5modules/backends.py +0 -1022
- pymodaq/utils/h5modules/browsing.py +0 -627
- pymodaq/utils/h5modules/data_saving.py +0 -1107
- pymodaq/utils/h5modules/exporter.py +0 -119
- pymodaq/utils/h5modules/exporters/__init__.py +0 -0
- pymodaq/utils/h5modules/exporters/base.py +0 -111
- pymodaq/utils/h5modules/exporters/flimj.py +0 -63
- pymodaq/utils/h5modules/exporters/hyperspy.py +0 -143
- pymodaq/utils/h5modules/saving.py +0 -866
- pymodaq/utils/h5modules/utils.py +0 -115
- pymodaq/utils/managers/action_manager.py +0 -489
- pymodaq/utils/managers/parameter_manager.py +0 -279
- pymodaq/utils/managers/roi_manager.py +0 -740
- pymodaq/utils/parameter/ioxml.py +0 -545
- pymodaq/utils/parameter/pymodaq_ptypes/__init__.py +0 -38
- pymodaq/utils/parameter/pymodaq_ptypes/bool.py +0 -31
- pymodaq/utils/parameter/pymodaq_ptypes/date.py +0 -126
- pymodaq/utils/parameter/pymodaq_ptypes/filedir.py +0 -143
- pymodaq/utils/parameter/pymodaq_ptypes/itemselect.py +0 -265
- pymodaq/utils/parameter/pymodaq_ptypes/led.py +0 -44
- pymodaq/utils/parameter/pymodaq_ptypes/list.py +0 -150
- pymodaq/utils/parameter/pymodaq_ptypes/numeric.py +0 -18
- pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +0 -175
- pymodaq/utils/parameter/pymodaq_ptypes/slide.py +0 -166
- pymodaq/utils/parameter/pymodaq_ptypes/table.py +0 -135
- pymodaq/utils/parameter/pymodaq_ptypes/tableview.py +0 -149
- pymodaq/utils/parameter/pymodaq_ptypes/text.py +0 -142
- pymodaq/utils/plotting/__init__.py +0 -0
- pymodaq/utils/plotting/data_viewers/__init__.py +0 -10
- pymodaq/utils/plotting/data_viewers/base.py +0 -286
- pymodaq/utils/plotting/data_viewers/viewer.py +0 -275
- pymodaq/utils/plotting/data_viewers/viewer0D.py +0 -298
- pymodaq/utils/plotting/data_viewers/viewer1D.py +0 -826
- pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +0 -231
- pymodaq/utils/plotting/data_viewers/viewer2D.py +0 -1118
- pymodaq/utils/plotting/data_viewers/viewer2D_basic.py +0 -146
- pymodaq/utils/plotting/data_viewers/viewerND.py +0 -800
- pymodaq/utils/plotting/gant_chart.py +0 -123
- pymodaq/utils/plotting/image_viewer.py +0 -97
- pymodaq/utils/plotting/items/__init__.py +0 -0
- pymodaq/utils/plotting/items/axis_scaled.py +0 -93
- pymodaq/utils/plotting/items/crosshair.py +0 -94
- pymodaq/utils/plotting/items/image.py +0 -388
- pymodaq/utils/plotting/navigator.py +0 -353
- pymodaq/utils/plotting/plotter/plotter.py +0 -94
- pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
- pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +0 -134
- pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +0 -78
- pymodaq/utils/plotting/utils/__init__.py +0 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +0 -88
- pymodaq/utils/plotting/utils/filter.py +0 -585
- pymodaq/utils/plotting/utils/lineout.py +0 -226
- pymodaq/utils/plotting/utils/plot_utils.py +0 -579
- pymodaq/utils/plotting/utils/signalND.py +0 -1347
- pymodaq/utils/plotting/widgets.py +0 -76
- pymodaq/utils/qvariant.py +0 -12
- pymodaq/utils/slicing.py +0 -63
- pymodaq/utils/units.py +0 -216
- pymodaq-4.4.7.dist-info/METADATA +0 -163
- pymodaq-4.4.7.dist-info/RECORD +0 -446
- /pymodaq/{post_treatment/daq_analysis → daq_utils}/__init__.py +0 -0
- /pymodaq/{utils/abstract/logger.py → extensions/daq_logger/abstract.py} +0 -0
- /pymodaq/{post_treatment/daq_measurement → extensions/daq_logger/db}/__init__.py +0 -0
- {pymodaq-4.4.7.dist-info → pymodaq-5.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,866 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created the 15/11/2022
|
|
4
|
-
|
|
5
|
-
@author: Sebastien Weber
|
|
6
|
-
"""
|
|
7
|
-
import copy
|
|
8
|
-
import datetime
|
|
9
|
-
from dateutil import parser
|
|
10
|
-
from numbers import Number
|
|
11
|
-
import os
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
from typing import Union, Iterable
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import numpy as np
|
|
17
|
-
from qtpy.QtCore import QObject, Signal
|
|
18
|
-
from qtpy import QtWidgets
|
|
19
|
-
|
|
20
|
-
from pymodaq.utils.logger import set_logger, get_module_name
|
|
21
|
-
from pymodaq.utils.parameter import Parameter, ParameterTree
|
|
22
|
-
from pymodaq.utils.parameter import utils as putils
|
|
23
|
-
from pymodaq.utils.managers.parameter_manager import ParameterManager
|
|
24
|
-
from pymodaq.utils.gui_utils.file_io import select_file
|
|
25
|
-
|
|
26
|
-
from pymodaq.utils.gui_utils.utils import dashboard_submodules_params
|
|
27
|
-
from pymodaq.utils import daq_utils as utils
|
|
28
|
-
from pymodaq.utils.config import Config
|
|
29
|
-
from pymodaq.utils.data import DataDim, DataToExport, Axis, DataWithAxes
|
|
30
|
-
from pymodaq.utils.enums import BaseEnum, enum_checker
|
|
31
|
-
from pymodaq.utils.scanner.utils import ScanType
|
|
32
|
-
from pymodaq.utils.messenger import deprecation_msg
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
from .backends import (H5Backend, backends_available, SaveType, InvalidSave, InvalidExport, InvalidDataType,
|
|
36
|
-
InvalidGroupType, InvalidGroupDataType, Node, GroupType, InvalidDataDimension, InvalidScanType,
|
|
37
|
-
GROUP, VLARRAY)
|
|
38
|
-
from . import browsing
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
config = Config()
|
|
42
|
-
logger = set_logger(get_module_name(__file__))
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class FileType(BaseEnum):
|
|
46
|
-
detector = 0
|
|
47
|
-
actuator = 1
|
|
48
|
-
axis = 2
|
|
49
|
-
scan = 3
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class DataType(BaseEnum):
|
|
53
|
-
data = 'Data'
|
|
54
|
-
axis = 'Axis'
|
|
55
|
-
live_scan = 'Live'
|
|
56
|
-
external_h5 = 'ExtData'
|
|
57
|
-
strings = 'Strings'
|
|
58
|
-
bkg = 'Bkg'
|
|
59
|
-
data_enlargeable = 'EnlData'
|
|
60
|
-
error = 'ErrorBar'
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class H5SaverLowLevel(H5Backend):
|
|
64
|
-
"""Object containing basic methods in order to structure and interact with a h5file compatible with the h5browser
|
|
65
|
-
|
|
66
|
-
See Also
|
|
67
|
-
--------
|
|
68
|
-
H5Browser
|
|
69
|
-
|
|
70
|
-
Attributes
|
|
71
|
-
----------
|
|
72
|
-
h5_file: pytables hdf5 file
|
|
73
|
-
object used to save all datas and metadas
|
|
74
|
-
h5_file_path: str or Path
|
|
75
|
-
The file path
|
|
76
|
-
"""
|
|
77
|
-
|
|
78
|
-
def __init__(self, save_type: SaveType = 'scan', backend='tables'):
|
|
79
|
-
H5Backend.__init__(self, backend)
|
|
80
|
-
|
|
81
|
-
self.save_type = enum_checker(SaveType, save_type)
|
|
82
|
-
|
|
83
|
-
self.h5_file_path = None
|
|
84
|
-
self.h5_file_name = None
|
|
85
|
-
self.file_loaded = False
|
|
86
|
-
|
|
87
|
-
self._current_group = None
|
|
88
|
-
self._raw_group: Union[GROUP, str] = '/RawData'
|
|
89
|
-
self._logger_array = None
|
|
90
|
-
|
|
91
|
-
@property
|
|
92
|
-
def raw_group(self):
|
|
93
|
-
return self._raw_group
|
|
94
|
-
|
|
95
|
-
@property
|
|
96
|
-
def h5_file(self):
|
|
97
|
-
return self._h5file
|
|
98
|
-
|
|
99
|
-
def init_file(self, file_name: Path, raw_group_name='RawData', new_file=False, metadata: dict = None):
|
|
100
|
-
"""Initializes a new h5 file.
|
|
101
|
-
|
|
102
|
-
Parameters
|
|
103
|
-
----------
|
|
104
|
-
file_name: Path
|
|
105
|
-
a complete Path pointing to a h5 file
|
|
106
|
-
raw_group_name: str
|
|
107
|
-
Base node name
|
|
108
|
-
new_file: bool
|
|
109
|
-
If True create a new file, otherwise append to a potential existing one
|
|
110
|
-
|
|
111
|
-
Returns
|
|
112
|
-
-------
|
|
113
|
-
bool
|
|
114
|
-
True if new file has been created, False otherwise
|
|
115
|
-
"""
|
|
116
|
-
datetime_now = datetime.datetime.now()
|
|
117
|
-
|
|
118
|
-
if file_name is not None and isinstance(file_name, Path):
|
|
119
|
-
self.h5_file_name = file_name.stem + ".h5"
|
|
120
|
-
self.h5_file_path = file_name.parent
|
|
121
|
-
if not self.h5_file_path.joinpath(self.h5_file_name).is_file():
|
|
122
|
-
new_file = True
|
|
123
|
-
|
|
124
|
-
else:
|
|
125
|
-
self.h5_file_name = select_file(save=True, ext='h5')
|
|
126
|
-
self.h5_file_path = self.h5_file_name.parent
|
|
127
|
-
new_file = True
|
|
128
|
-
|
|
129
|
-
self.close_file()
|
|
130
|
-
self.open_file(self.h5_file_path.joinpath(self.h5_file_name), 'w' if new_file else 'a', title='PyMoDAQ file')
|
|
131
|
-
|
|
132
|
-
self._raw_group = self.get_set_group(self.root(), raw_group_name, title='Data from PyMoDAQ modules')
|
|
133
|
-
self.get_set_logger(self._raw_group)
|
|
134
|
-
|
|
135
|
-
if new_file:
|
|
136
|
-
self._raw_group.attrs['type'] = self.save_type.name # first possibility to set a node attribute
|
|
137
|
-
self.root().set_attr('file', self.h5_file_name) # second possibility
|
|
138
|
-
|
|
139
|
-
self.set_attr(self.root(), 'date', datetime_now.date().isoformat())
|
|
140
|
-
self.set_attr(self.root(), 'time', datetime_now.time().isoformat())
|
|
141
|
-
|
|
142
|
-
if metadata is not None:
|
|
143
|
-
for metadata_key in metadata:
|
|
144
|
-
self._raw_group.attrs[metadata_key] = metadata[metadata_key]
|
|
145
|
-
|
|
146
|
-
def save_file(self, filename=None):
|
|
147
|
-
if filename is None:
|
|
148
|
-
filename = select_file(None, save=True, ext='h5')
|
|
149
|
-
if filename != '':
|
|
150
|
-
super().save_file_as(filename)
|
|
151
|
-
|
|
152
|
-
def get_set_logger(self, where: Node = None) -> VLARRAY:
|
|
153
|
-
""" Retrieve or create (if absent) a logger enlargeable array to store logs
|
|
154
|
-
Get attributed to the class attribute ``logger_array``
|
|
155
|
-
Parameters
|
|
156
|
-
----------
|
|
157
|
-
where: node
|
|
158
|
-
location within the tree where to save or retrieve the array
|
|
159
|
-
|
|
160
|
-
Returns
|
|
161
|
-
-------
|
|
162
|
-
vlarray
|
|
163
|
-
enlargeable array accepting strings as elements
|
|
164
|
-
"""
|
|
165
|
-
if where is None:
|
|
166
|
-
where = self.raw_group
|
|
167
|
-
if isinstance(where, Node):
|
|
168
|
-
where = where.node
|
|
169
|
-
logger = 'Logger'
|
|
170
|
-
if logger not in list(self.get_children(where)):
|
|
171
|
-
# check if logger node exist
|
|
172
|
-
self._logger_array = self.add_string_array(where, logger)
|
|
173
|
-
self._logger_array.attrs['type'] = 'log'
|
|
174
|
-
else:
|
|
175
|
-
self._logger_array = self.get_node(where, name=logger)
|
|
176
|
-
return self._logger_array
|
|
177
|
-
|
|
178
|
-
def add_log(self, msg):
|
|
179
|
-
self._logger_array.append(msg)
|
|
180
|
-
|
|
181
|
-
def add_string_array(self, where, name, title='', metadata=dict([])):
|
|
182
|
-
array = self.create_vlarray(where, name, dtype='string', title=title)
|
|
183
|
-
array.attrs['shape'] = (0,)
|
|
184
|
-
array.attrs['data_type'] = 'strings'
|
|
185
|
-
|
|
186
|
-
for metadat in metadata:
|
|
187
|
-
array.attrs[metadat] = metadata[metadat]
|
|
188
|
-
return array
|
|
189
|
-
|
|
190
|
-
def add_array(self, where: Union[GROUP, str], name: str, data_type: DataType, array_to_save: np.ndarray = None,
|
|
191
|
-
data_shape: tuple = None, array_type: np.dtype = None, data_dimension: DataDim = None,
|
|
192
|
-
scan_shape: tuple = tuple([]), add_scan_dim=False, enlargeable: bool = False,
|
|
193
|
-
title: str = '', metadata=dict([]), ):
|
|
194
|
-
|
|
195
|
-
"""save data arrays on the hdf5 file together with metadata
|
|
196
|
-
Parameters
|
|
197
|
-
----------
|
|
198
|
-
where: GROUP
|
|
199
|
-
node where to save the array
|
|
200
|
-
name: str
|
|
201
|
-
name of the array in the hdf5 file
|
|
202
|
-
data_type: DataType
|
|
203
|
-
mandatory so that the h5Browser can interpret correctly the array
|
|
204
|
-
data_shape: Iterable
|
|
205
|
-
the shape of the array to save, mandatory if array_to_save is None
|
|
206
|
-
data_dimension: DataDim
|
|
207
|
-
The data's dimension
|
|
208
|
-
scan_shape: Iterable
|
|
209
|
-
the shape of the scan dimensions
|
|
210
|
-
title: str
|
|
211
|
-
the title attribute of the array node
|
|
212
|
-
array_to_save: ndarray or None
|
|
213
|
-
data to be saved in the array. If None, array_type and data_shape should be specified in order to init
|
|
214
|
-
correctly the memory
|
|
215
|
-
array_type: np.dtype or numpy types
|
|
216
|
-
eg np.float, np.int32 ...
|
|
217
|
-
enlargeable: bool
|
|
218
|
-
if False, data are saved as a CARRAY, otherwise as a EARRAY (for ragged data, see add_string_array)
|
|
219
|
-
metadata: dict
|
|
220
|
-
dictionnary whose keys will be saved as the array attributes
|
|
221
|
-
add_scan_dim: if True, the scan axes dimension (scan_shape iterable) is prepended to the array shape on the hdf5
|
|
222
|
-
In that case, the array is usually initialized as zero and further populated
|
|
223
|
-
|
|
224
|
-
Returns
|
|
225
|
-
-------
|
|
226
|
-
array (CARRAY or EARRAY)
|
|
227
|
-
|
|
228
|
-
See Also
|
|
229
|
-
--------
|
|
230
|
-
add_data, add_string_array
|
|
231
|
-
"""
|
|
232
|
-
if array_type is None:
|
|
233
|
-
if array_to_save is None:
|
|
234
|
-
array_type = config('data_saving', 'data_type', 'dynamic')
|
|
235
|
-
else:
|
|
236
|
-
array_type = array_to_save.dtype
|
|
237
|
-
|
|
238
|
-
data_type = enum_checker(DataType, data_type)
|
|
239
|
-
data_dimension = enum_checker(DataDim, data_dimension)
|
|
240
|
-
|
|
241
|
-
if enlargeable:
|
|
242
|
-
# if data_shape == (1,):
|
|
243
|
-
# data_shape = None
|
|
244
|
-
array = self.create_earray(where, utils.capitalize(name), dtype=np.dtype(array_type),
|
|
245
|
-
data_shape=data_shape, title=title)
|
|
246
|
-
else:
|
|
247
|
-
if add_scan_dim: # means it is an array initialization to zero
|
|
248
|
-
shape = list(scan_shape[:])
|
|
249
|
-
if not(len(data_shape) == 1 and data_shape[0] == 1): # means data are not ndarrays of scalars
|
|
250
|
-
shape.extend(data_shape)
|
|
251
|
-
if array_to_save is None:
|
|
252
|
-
array_to_save = np.zeros(shape, dtype=np.dtype(array_type))
|
|
253
|
-
|
|
254
|
-
array = self.create_carray(where, utils.capitalize(name), obj=array_to_save, title=title)
|
|
255
|
-
self.set_attr(array, 'data_type', data_type.name)
|
|
256
|
-
self.set_attr(array, 'data_dimension', data_dimension.name)
|
|
257
|
-
|
|
258
|
-
for metadat in metadata:
|
|
259
|
-
self.set_attr(array, metadat, metadata[metadat])
|
|
260
|
-
return array
|
|
261
|
-
|
|
262
|
-
def get_set_group(self, where, name, title=''):
|
|
263
|
-
"""Get the group located at where if it exists otherwise creates it
|
|
264
|
-
|
|
265
|
-
This also set the _current_group property
|
|
266
|
-
"""
|
|
267
|
-
self._current_group = super().get_set_group(where, name, title)
|
|
268
|
-
return self._current_group
|
|
269
|
-
|
|
270
|
-
def get_groups(self, where: Union[str, GROUP], group_type: GroupType):
|
|
271
|
-
"""Get all groups hanging from a Group and of a certain type"""
|
|
272
|
-
groups = []
|
|
273
|
-
for node_name in list(self.get_children(where)):
|
|
274
|
-
group = self.get_node(where, node_name)
|
|
275
|
-
if 'type' in group.attrs and group.attrs['type'] == group_type.name:
|
|
276
|
-
groups.append(group)
|
|
277
|
-
return groups
|
|
278
|
-
|
|
279
|
-
def get_last_group(self, where: GROUP, group_type: GroupType):
|
|
280
|
-
groups = self.get_groups(where, group_type)
|
|
281
|
-
if len(groups) != 0:
|
|
282
|
-
return groups[-1]
|
|
283
|
-
else:
|
|
284
|
-
return None
|
|
285
|
-
|
|
286
|
-
def get_node_from_attribute_match(self, where, attr_name, attr_value):
|
|
287
|
-
"""Get a Node starting from a given node (Group) matching a pair of node attribute name and value"""
|
|
288
|
-
for node in self.walk_nodes(where):
|
|
289
|
-
if attr_name in node.attrs and node.attrs[attr_name] == attr_value:
|
|
290
|
-
return node
|
|
291
|
-
|
|
292
|
-
def get_node_from_title(self, where, title: str):
|
|
293
|
-
"""Get a Node starting from a given node (Group) matching the given title"""
|
|
294
|
-
return self.get_node_from_attribute_match(where, 'TITLE', title)
|
|
295
|
-
|
|
296
|
-
def add_data_group(self, where, data_dim: DataDim, title='', settings_as_xml='', metadata=dict([])):
|
|
297
|
-
"""Creates a group node at given location in the tree
|
|
298
|
-
|
|
299
|
-
Parameters
|
|
300
|
-
----------
|
|
301
|
-
where: group node
|
|
302
|
-
where to create data group
|
|
303
|
-
group_data_type: DataDim
|
|
304
|
-
title: str, optional
|
|
305
|
-
a title for this node, will be saved as metadata
|
|
306
|
-
settings_as_xml: str, optional
|
|
307
|
-
XML string created from a Parameter object to be saved as metadata
|
|
308
|
-
metadata: dict, optional
|
|
309
|
-
will be saved as a new metadata attribute with name: key and value: dict value
|
|
310
|
-
|
|
311
|
-
Returns
|
|
312
|
-
-------
|
|
313
|
-
group: group node
|
|
314
|
-
|
|
315
|
-
See Also
|
|
316
|
-
--------
|
|
317
|
-
:py:meth:`add_group`
|
|
318
|
-
"""
|
|
319
|
-
data_dim = enum_checker(DataDim, data_dim)
|
|
320
|
-
metadata.update(settings=settings_as_xml)
|
|
321
|
-
group = self.add_group(data_dim.name, 'data_dim', where, title, metadata)
|
|
322
|
-
return group
|
|
323
|
-
|
|
324
|
-
def add_incremental_group(self, group_type, where, title='', settings_as_xml='', metadata=dict([])):
|
|
325
|
-
"""
|
|
326
|
-
Add a node in the h5 file tree of the group type with an increment in the given name
|
|
327
|
-
Parameters
|
|
328
|
-
----------
|
|
329
|
-
group_type: str or GroupType enum
|
|
330
|
-
one of the possible values of **group_types**
|
|
331
|
-
where: str or node
|
|
332
|
-
parent node where to create the new group
|
|
333
|
-
title: str
|
|
334
|
-
node title
|
|
335
|
-
settings_as_xml: str
|
|
336
|
-
XML string containing Parameter representation
|
|
337
|
-
metadata: dict
|
|
338
|
-
extra metadata to be saved with this new group node
|
|
339
|
-
|
|
340
|
-
Returns
|
|
341
|
-
-------
|
|
342
|
-
node: newly created group node
|
|
343
|
-
"""
|
|
344
|
-
group_type = enum_checker(GroupType, group_type)
|
|
345
|
-
|
|
346
|
-
nodes = [name for name in self.get_children(self.get_node(where))]
|
|
347
|
-
nodes_tmp = []
|
|
348
|
-
for node in nodes:
|
|
349
|
-
if utils.capitalize(group_type.name) in node:
|
|
350
|
-
nodes_tmp.append(node)
|
|
351
|
-
nodes_tmp.sort()
|
|
352
|
-
if len(nodes_tmp) == 0:
|
|
353
|
-
ind_group = -1
|
|
354
|
-
else:
|
|
355
|
-
ind_group = int(nodes_tmp[-1][-3:])
|
|
356
|
-
group = self.get_set_group(where, f'{utils.capitalize(group_type.name)}{ind_group + 1:03d}', title)
|
|
357
|
-
self.set_attr(group, 'settings', settings_as_xml)
|
|
358
|
-
if group_type.name.lower() != 'ch':
|
|
359
|
-
self.set_attr(group, 'type', group_type.name.lower())
|
|
360
|
-
else:
|
|
361
|
-
self.set_attr(group, 'type', '')
|
|
362
|
-
for metadat in metadata:
|
|
363
|
-
self.set_attr(group, metadat, metadata[metadat])
|
|
364
|
-
return group
|
|
365
|
-
|
|
366
|
-
def add_act_group(self, where, title='', settings_as_xml='', metadata=dict([])):
|
|
367
|
-
"""
|
|
368
|
-
Add a new group of type detector
|
|
369
|
-
See Also
|
|
370
|
-
-------
|
|
371
|
-
add_incremental_group
|
|
372
|
-
"""
|
|
373
|
-
group = self.add_incremental_group('actuator', where, title, settings_as_xml, metadata)
|
|
374
|
-
return group
|
|
375
|
-
|
|
376
|
-
def add_det_group(self, where, title='', settings_as_xml='', metadata=dict([])):
|
|
377
|
-
"""
|
|
378
|
-
Add a new group of type detector
|
|
379
|
-
See Also
|
|
380
|
-
-------
|
|
381
|
-
add_incremental_group
|
|
382
|
-
"""
|
|
383
|
-
group = self.add_incremental_group('detector', where, title, settings_as_xml, metadata)
|
|
384
|
-
return group
|
|
385
|
-
|
|
386
|
-
def add_scan_group(self, where='/RawData', title='', settings_as_xml='', metadata=dict([])):
|
|
387
|
-
"""Add a new group of type scan
|
|
388
|
-
|
|
389
|
-
At creation adds the attributes description and scan_done to be used elsewhere
|
|
390
|
-
|
|
391
|
-
See Also
|
|
392
|
-
-------
|
|
393
|
-
add_incremental_group
|
|
394
|
-
"""
|
|
395
|
-
metadata.update(dict(description='', scan_done=False))
|
|
396
|
-
group = self.add_incremental_group(GroupType['scan'], where, title, settings_as_xml, metadata)
|
|
397
|
-
return group
|
|
398
|
-
|
|
399
|
-
def add_ch_group(self, where, title='', settings_as_xml='', metadata=dict([])):
|
|
400
|
-
"""
|
|
401
|
-
Add a new group of type channel
|
|
402
|
-
See Also
|
|
403
|
-
-------
|
|
404
|
-
add_incremental_group
|
|
405
|
-
"""
|
|
406
|
-
group = self.add_incremental_group('ch', where, title, settings_as_xml, metadata)
|
|
407
|
-
return group
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
def add_move_group(self, where, title='', settings_as_xml='', metadata=dict([])):
|
|
411
|
-
"""
|
|
412
|
-
Add a new group of type actuator
|
|
413
|
-
See Also
|
|
414
|
-
-------
|
|
415
|
-
add_incremental_group
|
|
416
|
-
"""
|
|
417
|
-
group = self.add_incremental_group('actuator', where, title, settings_as_xml, metadata)
|
|
418
|
-
return group
|
|
419
|
-
|
|
420
|
-
def show_file_content(self):
|
|
421
|
-
win = QtWidgets.QMainWindow()
|
|
422
|
-
if not self.isopen():
|
|
423
|
-
if self.h5_file_path is not None:
|
|
424
|
-
if self.h5_file_path.exists():
|
|
425
|
-
self.analysis_prog = browsing.H5Browser(win, h5file_path=self.h5_file_path)
|
|
426
|
-
else:
|
|
427
|
-
logger.warning('The h5 file path has not been defined yet')
|
|
428
|
-
else:
|
|
429
|
-
logger.warning('The h5 file path has not been defined yet')
|
|
430
|
-
else:
|
|
431
|
-
self.flush()
|
|
432
|
-
self.analysis_prog = browsing.H5Browser(win, h5file=self.h5file)
|
|
433
|
-
win.show()
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
class H5SaverBase(H5SaverLowLevel, ParameterManager):
|
|
437
|
-
"""Object containing all methods in order to save datas in a *hdf5 file* with a hierarchy compatible with
|
|
438
|
-
the H5Browser. The saving parameters are contained within a **Parameter** object: self.settings that can be displayed
|
|
439
|
-
on a UI using the widget self.settings_tree. At the creation of a new file, a node
|
|
440
|
-
group named **Raw_datas** and represented by the attribute ``raw_group`` is created and set with a metadata attribute:
|
|
441
|
-
|
|
442
|
-
* 'type' given by the **save_type** class parameter
|
|
443
|
-
|
|
444
|
-
The root group of the file is then set with a few metadata:
|
|
445
|
-
|
|
446
|
-
* 'pymodaq_version' the current pymodaq version, e.g. 1.6.2
|
|
447
|
-
* 'file' the file name
|
|
448
|
-
* 'date' the current date
|
|
449
|
-
* 'time' the current time
|
|
450
|
-
|
|
451
|
-
All datas will then be saved under this node in various groups
|
|
452
|
-
|
|
453
|
-
See Also
|
|
454
|
-
--------
|
|
455
|
-
H5Browser
|
|
456
|
-
|
|
457
|
-
Parameters
|
|
458
|
-
----------
|
|
459
|
-
h5_file: pytables hdf5 file
|
|
460
|
-
object used to save all datas and metadas
|
|
461
|
-
h5_file_path: str or Path
|
|
462
|
-
Signal signal represented by a float. Is emitted each time the hardware reached the target
|
|
463
|
-
position within the epsilon precision (see comon_parameters variable)
|
|
464
|
-
save_type: str
|
|
465
|
-
an element of the enum module attribute SaveType
|
|
466
|
-
* 'scan' is used for DAQScan module and should be used for similar application
|
|
467
|
-
* 'detector' is used for DAQ_Viewer module and should be used for similar application
|
|
468
|
-
* 'custom' should be used for customized applications
|
|
469
|
-
|
|
470
|
-
Attributes
|
|
471
|
-
----------
|
|
472
|
-
|
|
473
|
-
settings: Parameter
|
|
474
|
-
Parameter instance (pyqtgraph) containing all settings (could be represented using the settings_tree widget)
|
|
475
|
-
|
|
476
|
-
settings_tree: ParameterTree
|
|
477
|
-
Widget representing as a Tree structure, all the settings defined in the class preamble variable ``params``
|
|
478
|
-
|
|
479
|
-
"""
|
|
480
|
-
settings_name = 'h5saver_settings'
|
|
481
|
-
params = [
|
|
482
|
-
{'title': 'Save type:', 'name': 'save_type', 'type': 'list', 'limits': SaveType.names(), 'readonly': True},
|
|
483
|
-
] + dashboard_submodules_params + \
|
|
484
|
-
[{'title': 'Backend:', 'name': 'backend', 'type': 'group', 'children': [
|
|
485
|
-
{'title': 'Backend type:', 'name': 'backend_type', 'type': 'list', 'limits': backends_available,
|
|
486
|
-
'readonly': True},
|
|
487
|
-
{'title': 'HSDS Server:', 'name': 'hsds_options', 'type': 'group', 'visible': False, 'children': [
|
|
488
|
-
{'title': 'Endpoint:', 'name': 'endpoint', 'type': 'str',
|
|
489
|
-
'value': config('data_saving', 'hsds', 'root_url'), 'readonly': False},
|
|
490
|
-
{'title': 'User:', 'name': 'user', 'type': 'str',
|
|
491
|
-
'value': config('data_saving', 'hsds', 'username'), 'readonly': False},
|
|
492
|
-
{'title': 'password:', 'name': 'password', 'type': 'str',
|
|
493
|
-
'value': config('data_saving', 'hsds', 'pwd'), 'readonly': False},
|
|
494
|
-
]},
|
|
495
|
-
]},
|
|
496
|
-
|
|
497
|
-
{'title': 'custom_name?:', 'name': 'custom_name', 'type': 'bool', 'default': False, 'value': False},
|
|
498
|
-
{'title': 'show file content?', 'name': 'show_file', 'type': 'bool_push', 'default': False,
|
|
499
|
-
'value': False},
|
|
500
|
-
{'title': 'Base path:', 'name': 'base_path', 'type': 'browsepath',
|
|
501
|
-
'value': config('data_saving', 'h5file', 'save_path'), 'filetype': False, 'readonly': True, },
|
|
502
|
-
{'title': 'Base name:', 'name': 'base_name', 'type': 'str', 'value': 'Scan', 'readonly': True},
|
|
503
|
-
{'title': 'Current scan:', 'name': 'current_scan_name', 'type': 'str', 'value': '', 'readonly': True},
|
|
504
|
-
{'title': 'Current path:', 'name': 'current_scan_path', 'type': 'text',
|
|
505
|
-
'value': config('data_saving', 'h5file', 'save_path'), 'readonly': True, 'visible': False},
|
|
506
|
-
{'title': 'h5file:', 'name': 'current_h5_file', 'type': 'text', 'value': '', 'readonly': True},
|
|
507
|
-
{'title': 'New file', 'name': 'new_file', 'type': 'action'},
|
|
508
|
-
{'title': 'Saving dynamic', 'name': 'dynamic', 'type': 'list',
|
|
509
|
-
'limits': config('data_saving', 'data_type', 'dynamics'),
|
|
510
|
-
'value': config('data_saving', 'data_type', 'dynamic')},
|
|
511
|
-
{'title': 'Compression options:', 'name': 'compression_options', 'type': 'group', 'children': [
|
|
512
|
-
{'title': 'Compression library:', 'name': 'h5comp_library', 'type': 'list', 'value': 'zlib',
|
|
513
|
-
'limits': ['zlib', 'gzip']},
|
|
514
|
-
{'title': 'Compression level:', 'name': 'h5comp_level', 'type': 'int',
|
|
515
|
-
'value': config('data_saving', 'h5file', 'compression_level'), 'min': 0, 'max': 9},
|
|
516
|
-
]},
|
|
517
|
-
]
|
|
518
|
-
|
|
519
|
-
def __init__(self, save_type='scan', backend='tables'):
|
|
520
|
-
"""
|
|
521
|
-
|
|
522
|
-
Parameters
|
|
523
|
-
----------
|
|
524
|
-
save_type (str): one of ['scan', 'detector', 'logger', 'custom']
|
|
525
|
-
backend (str): either 'tables' for pytables backend, 'h5py' for h5py backends or 'h5pyd' for HSDS backend
|
|
526
|
-
|
|
527
|
-
See Also
|
|
528
|
-
--------
|
|
529
|
-
https://github.com/HDFGroup/hsds
|
|
530
|
-
"""
|
|
531
|
-
H5SaverLowLevel.__init__(self, save_type, backend)
|
|
532
|
-
ParameterManager.__init__(self)
|
|
533
|
-
|
|
534
|
-
self.current_scan_group = None
|
|
535
|
-
self.current_scan_name = None
|
|
536
|
-
|
|
537
|
-
self.settings.child('save_type').setValue(self.save_type.name)
|
|
538
|
-
|
|
539
|
-
def show_settings(self, show=True):
|
|
540
|
-
self.settings_tree.setVisible(show)
|
|
541
|
-
|
|
542
|
-
def init_file(self, update_h5=False, custom_naming=False, addhoc_file_path=None, metadata=dict([])):
|
|
543
|
-
"""Initializes a new h5 file.
|
|
544
|
-
Could set the h5_file attributes as:
|
|
545
|
-
|
|
546
|
-
* a file with a name following a template if ``custom_naming`` is ``False`` and ``addhoc_file_path`` is ``None``
|
|
547
|
-
* a file within a name set using a file dialog popup if ``custom_naming`` is ``True``
|
|
548
|
-
* a file with a custom name if ``addhoc_file_path`` is a ``Path`` object or a path string
|
|
549
|
-
|
|
550
|
-
Parameters
|
|
551
|
-
----------
|
|
552
|
-
update_h5: bool
|
|
553
|
-
create a new h5 file with name specified by other parameters
|
|
554
|
-
if false try to open an existing file and will append new data to it
|
|
555
|
-
custom_naming: bool
|
|
556
|
-
if True, a selection file dialog opens to set a new file name
|
|
557
|
-
addhoc_file_path: Path or str
|
|
558
|
-
supplied name by the user for the new file
|
|
559
|
-
metadata: dict
|
|
560
|
-
dictionnary with pair of key, value that should be saved as attributes of the root group
|
|
561
|
-
Returns
|
|
562
|
-
-------
|
|
563
|
-
update_h5: bool
|
|
564
|
-
True if new file has been created, False otherwise
|
|
565
|
-
"""
|
|
566
|
-
datetime_now = datetime.datetime.now()
|
|
567
|
-
if addhoc_file_path is None:
|
|
568
|
-
if not os.path.isdir(self.settings['base_path']):
|
|
569
|
-
os.mkdir(self.settings['base_path'])
|
|
570
|
-
|
|
571
|
-
# set the filename and path
|
|
572
|
-
base_name = self.settings['base_name']
|
|
573
|
-
|
|
574
|
-
if not custom_naming:
|
|
575
|
-
custom_naming = self.settings['custom_name']
|
|
576
|
-
|
|
577
|
-
if not custom_naming:
|
|
578
|
-
scan_type = self.settings['save_type'] == 'scan'
|
|
579
|
-
scan_path, current_scan_name, save_path = self.update_file_paths(update_h5)
|
|
580
|
-
self.current_scan_name = current_scan_name
|
|
581
|
-
self.settings.child('current_scan_name').setValue(current_scan_name)
|
|
582
|
-
self.settings.child('current_scan_path').setValue(str(scan_path))
|
|
583
|
-
|
|
584
|
-
if not scan_type:
|
|
585
|
-
self.h5_file_path = save_path.parent # will remove the dataset part used for DAQ_scan datas
|
|
586
|
-
self.h5_file_name = base_name + datetime_now.strftime('_%Y%m%d_%H_%M_%S.h5')
|
|
587
|
-
else:
|
|
588
|
-
self.h5_file_name = save_path.name + ".h5"
|
|
589
|
-
self.h5_file_path = save_path.parent
|
|
590
|
-
|
|
591
|
-
else:
|
|
592
|
-
self.h5_file_name = select_file(start_path=base_name, save=True, ext='h5')
|
|
593
|
-
self.h5_file_path = self.h5_file_name.parent
|
|
594
|
-
|
|
595
|
-
else:
|
|
596
|
-
if isinstance(addhoc_file_path, str):
|
|
597
|
-
addhoc_file_path = Path(addhoc_file_path)
|
|
598
|
-
self.h5_file_path = addhoc_file_path.parent
|
|
599
|
-
self.h5_file_name = addhoc_file_path.name
|
|
600
|
-
|
|
601
|
-
fullpathname = self.h5_file_path.joinpath(self.h5_file_name)
|
|
602
|
-
self.settings.child('current_h5_file').setValue(str(fullpathname))
|
|
603
|
-
|
|
604
|
-
super().init_file(fullpathname, new_file=update_h5, metadata=metadata)
|
|
605
|
-
|
|
606
|
-
self.get_set_logger(self.raw_group)
|
|
607
|
-
|
|
608
|
-
return update_h5
|
|
609
|
-
|
|
610
|
-
def update_file_paths(self, update_h5=False):
|
|
611
|
-
"""
|
|
612
|
-
|
|
613
|
-
Parameters
|
|
614
|
-
----------
|
|
615
|
-
update_h5: bool
|
|
616
|
-
if True, will increment the file name and eventually the current scan index
|
|
617
|
-
if False, get the current scan index in the h5 file
|
|
618
|
-
|
|
619
|
-
Returns
|
|
620
|
-
-------
|
|
621
|
-
scan_path: Path
|
|
622
|
-
current_filename: str
|
|
623
|
-
dataset_path: Path
|
|
624
|
-
|
|
625
|
-
"""
|
|
626
|
-
|
|
627
|
-
try:
|
|
628
|
-
# set the filename and path
|
|
629
|
-
base_path = self.settings['base_path']
|
|
630
|
-
base_name = self.settings['base_name']
|
|
631
|
-
current_scan = self.settings['current_scan_name']
|
|
632
|
-
scan_type = self.settings['save_type'] == 'scan'
|
|
633
|
-
ind_dataset = None
|
|
634
|
-
if current_scan == '' or update_h5:
|
|
635
|
-
next_scan_index = 0
|
|
636
|
-
update_h5 = True # just started the main program so one should create a new h5
|
|
637
|
-
self.file_loaded = False
|
|
638
|
-
else:
|
|
639
|
-
next_scan_index = self.get_scan_index()
|
|
640
|
-
if self.file_loaded:
|
|
641
|
-
ind_dataset = int(os.path.splitext(self.h5_file_name)[0][-3:])
|
|
642
|
-
try:
|
|
643
|
-
curr_date = datetime.date.fromisoformat(self.get_attr(self.root(), 'date'))
|
|
644
|
-
except ValueError:
|
|
645
|
-
curr_date = parser.parse(self.get_attr(self.root(), 'date')).date()
|
|
646
|
-
else:
|
|
647
|
-
curr_date = datetime.date.today()
|
|
648
|
-
|
|
649
|
-
scan_path, current_filename, dataset_path = self.set_current_scan_path(base_path, base_name, update_h5,
|
|
650
|
-
next_scan_index,
|
|
651
|
-
create_dataset_folder=False,
|
|
652
|
-
curr_date=curr_date,
|
|
653
|
-
ind_dataset=ind_dataset)
|
|
654
|
-
self.settings.child('current_scan_path').setValue(str(dataset_path))
|
|
655
|
-
|
|
656
|
-
return scan_path, current_filename, dataset_path
|
|
657
|
-
|
|
658
|
-
except Exception as e:
|
|
659
|
-
logger.exception(str(e))
|
|
660
|
-
|
|
661
|
-
@classmethod
|
|
662
|
-
def find_part_in_path_and_subpath(cls, base_dir, part='', create=False, increment=True):
|
|
663
|
-
"""
|
|
664
|
-
Find path from part time.
|
|
665
|
-
|
|
666
|
-
=============== ============ =============================================
|
|
667
|
-
**Parameters** **Type** **Description**
|
|
668
|
-
*base_dir* Path object The directory to browse
|
|
669
|
-
*part* string The date of the directory to find/create
|
|
670
|
-
*create* boolean Indicate the creation flag of the directory
|
|
671
|
-
=============== ============ =============================================
|
|
672
|
-
|
|
673
|
-
Returns
|
|
674
|
-
-------
|
|
675
|
-
Path object
|
|
676
|
-
found path from part
|
|
677
|
-
"""
|
|
678
|
-
found_path = None
|
|
679
|
-
if part in base_dir.parts: # check if current year is in the given base path
|
|
680
|
-
if base_dir.name == part:
|
|
681
|
-
found_path = base_dir
|
|
682
|
-
else:
|
|
683
|
-
for ind in range(len(base_dir.parts)):
|
|
684
|
-
tmp_path = base_dir.parents[ind]
|
|
685
|
-
if tmp_path.name == part:
|
|
686
|
-
found_path = base_dir.parents[ind]
|
|
687
|
-
break
|
|
688
|
-
else: # if not check if year is in the subfolders
|
|
689
|
-
subfolders_year_name = [x.name for x in base_dir.iterdir() if x.is_dir()]
|
|
690
|
-
subfolders_found_path = [x for x in base_dir.iterdir() if x.is_dir()]
|
|
691
|
-
if part not in subfolders_year_name:
|
|
692
|
-
if increment:
|
|
693
|
-
found_path = base_dir.joinpath(part)
|
|
694
|
-
else:
|
|
695
|
-
found_path = base_dir
|
|
696
|
-
if create:
|
|
697
|
-
found_path.mkdir()
|
|
698
|
-
else:
|
|
699
|
-
ind_path = subfolders_year_name.index(part)
|
|
700
|
-
found_path = subfolders_found_path[ind_path]
|
|
701
|
-
return found_path
|
|
702
|
-
|
|
703
|
-
@classmethod
|
|
704
|
-
def set_current_scan_path(cls, base_dir, base_name='Scan', update_h5=False, next_scan_index=0,
|
|
705
|
-
create_scan_folder=False,
|
|
706
|
-
create_dataset_folder=True, curr_date=None, ind_dataset=None):
|
|
707
|
-
"""
|
|
708
|
-
|
|
709
|
-
Parameters
|
|
710
|
-
----------
|
|
711
|
-
base_dir
|
|
712
|
-
base_name
|
|
713
|
-
update_h5
|
|
714
|
-
next_scan_index
|
|
715
|
-
create_scan_folder
|
|
716
|
-
create_dataset_folder
|
|
717
|
-
|
|
718
|
-
Returns
|
|
719
|
-
-------
|
|
720
|
-
|
|
721
|
-
"""
|
|
722
|
-
base_dir = Path(base_dir)
|
|
723
|
-
if curr_date is None:
|
|
724
|
-
curr_date = datetime.date.today()
|
|
725
|
-
|
|
726
|
-
year_path = cls.find_part_in_path_and_subpath(base_dir, part=str(curr_date.year),
|
|
727
|
-
create=True) # create directory of the year if it doen't exist and return it
|
|
728
|
-
day_path = cls.find_part_in_path_and_subpath(year_path, part=curr_date.strftime('%Y%m%d'),
|
|
729
|
-
create=True) # create directory of the day if it doen't exist and return it
|
|
730
|
-
dataset_base_name = curr_date.strftime('Dataset_%Y%m%d')
|
|
731
|
-
dataset_paths = sorted([path for path in day_path.glob(dataset_base_name + "*"+".h5") if path.is_file()])
|
|
732
|
-
|
|
733
|
-
if ind_dataset is None:
|
|
734
|
-
if dataset_paths == []:
|
|
735
|
-
|
|
736
|
-
ind_dataset = 0
|
|
737
|
-
else:
|
|
738
|
-
if update_h5:
|
|
739
|
-
ind_dataset = int(dataset_paths[-1].stem.partition(dataset_base_name + "_")[2]) + 1
|
|
740
|
-
else:
|
|
741
|
-
ind_dataset = int(dataset_paths[-1].stem.partition(dataset_base_name + "_")[2])
|
|
742
|
-
|
|
743
|
-
dataset_path = cls.find_part_in_path_and_subpath(day_path,
|
|
744
|
-
part=dataset_base_name + "_{:03d}".format(ind_dataset),
|
|
745
|
-
create=False, increment=True)
|
|
746
|
-
scan_paths = sorted([path for path in dataset_path.glob(base_name + '*') if path.is_dir()])
|
|
747
|
-
ind_scan = next_scan_index
|
|
748
|
-
return dataset_path, base_name + '{:03d}'.format(ind_scan), dataset_path
|
|
749
|
-
|
|
750
|
-
def get_last_scan(self):
|
|
751
|
-
"""Gets the last scan node within the h5_file and under the **raw_group**
|
|
752
|
-
|
|
753
|
-
Returns
|
|
754
|
-
-------
|
|
755
|
-
scan_group: pytables group or None
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
"""
|
|
759
|
-
return self.get_last_group(self.raw_group, GroupType['scan'])
|
|
760
|
-
|
|
761
|
-
def get_scan_groups(self):
|
|
762
|
-
return self.get_groups(self.raw_group, GroupType['scan'])
|
|
763
|
-
|
|
764
|
-
def get_scan_index(self):
|
|
765
|
-
""" return the scan group index in the "scan templating": Scan000, Scan001 as an integer
|
|
766
|
-
"""
|
|
767
|
-
|
|
768
|
-
last_scan = self.get_last_scan()
|
|
769
|
-
return int(last_scan.name[4:]) if last_scan is not None else 0
|
|
770
|
-
|
|
771
|
-
def load_file(self, base_path=None, file_path=None):
|
|
772
|
-
"""Opens a file dialog to select a h5file saved on disk to be used
|
|
773
|
-
|
|
774
|
-
Parameters
|
|
775
|
-
----------
|
|
776
|
-
base_path
|
|
777
|
-
file_path
|
|
778
|
-
|
|
779
|
-
See Also
|
|
780
|
-
--------
|
|
781
|
-
:py:meth:`init_file`
|
|
782
|
-
|
|
783
|
-
"""
|
|
784
|
-
if base_path is None:
|
|
785
|
-
base_path = self.settings.child('base_path').value()
|
|
786
|
-
if not os.path.isdir(base_path):
|
|
787
|
-
base_path = None
|
|
788
|
-
|
|
789
|
-
if file_path is None:
|
|
790
|
-
file_path = select_file(base_path, save=False, ext='h5')
|
|
791
|
-
|
|
792
|
-
if not (file_path is None or file_path == ''):
|
|
793
|
-
if not isinstance(file_path, Path):
|
|
794
|
-
file_path = Path(file_path)
|
|
795
|
-
|
|
796
|
-
if 'h5' not in file_path.suffix:
|
|
797
|
-
raise IOError('Invalid file type, should be a h5 file')
|
|
798
|
-
|
|
799
|
-
self.init_file(addhoc_file_path=file_path)
|
|
800
|
-
self.file_loaded = True
|
|
801
|
-
|
|
802
|
-
def save_file(self, filename=None):
|
|
803
|
-
if filename is None:
|
|
804
|
-
filename = select_file(None, save=True, ext='h5')
|
|
805
|
-
if filename != '':
|
|
806
|
-
super().save_file_as(filename)
|
|
807
|
-
|
|
808
|
-
def value_changed(self, param):
|
|
809
|
-
if param.name() == 'show_file':
|
|
810
|
-
if param.value():
|
|
811
|
-
param.setValue(False)
|
|
812
|
-
self.show_file_content()
|
|
813
|
-
|
|
814
|
-
elif param.name() == 'base_path':
|
|
815
|
-
try:
|
|
816
|
-
if not os.path.isdir(param.value()):
|
|
817
|
-
os.mkdir(param.value())
|
|
818
|
-
except Exception as e:
|
|
819
|
-
self.update_status(f"The base path couldn't be set, please check your options: {str(e)}")
|
|
820
|
-
|
|
821
|
-
elif param.name() in putils.iter_children(self.settings.child('compression_options'), []):
|
|
822
|
-
compression = self.settings.child('compression_options', 'h5comp_library').value()
|
|
823
|
-
compression_opts = self.settings.child('compression_options', 'h5comp_level').value()
|
|
824
|
-
self.define_compression(compression, compression_opts)
|
|
825
|
-
|
|
826
|
-
def update_status(self, status):
|
|
827
|
-
logger.warning(status)
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
class H5Saver(H5SaverBase, QObject):
|
|
831
|
-
"""
|
|
832
|
-
status_sig: Signal
|
|
833
|
-
emits a signal of type Threadcommand in order to senf log information to a main UI
|
|
834
|
-
new_file_sig: Signal
|
|
835
|
-
emits a boolean signal to let the program know when the user pressed the new file button on the UI
|
|
836
|
-
"""
|
|
837
|
-
|
|
838
|
-
status_sig = Signal(utils.ThreadCommand)
|
|
839
|
-
new_file_sig = Signal(bool)
|
|
840
|
-
|
|
841
|
-
def __init__(self, *args, **kwargs):
|
|
842
|
-
"""
|
|
843
|
-
|
|
844
|
-
Parameters
|
|
845
|
-
----------
|
|
846
|
-
args
|
|
847
|
-
kwargs
|
|
848
|
-
"""
|
|
849
|
-
QObject.__init__(self)
|
|
850
|
-
H5SaverBase.__init__(self, *args, **kwargs)
|
|
851
|
-
|
|
852
|
-
self.settings.child('new_file').sigActivated.connect(lambda: self.emit_new_file(True))
|
|
853
|
-
|
|
854
|
-
def close(self):
|
|
855
|
-
self.close_file()
|
|
856
|
-
|
|
857
|
-
def emit_new_file(self, status):
|
|
858
|
-
"""Emits the new_file_sig
|
|
859
|
-
|
|
860
|
-
Parameters
|
|
861
|
-
----------
|
|
862
|
-
status: bool
|
|
863
|
-
emits True if a new file has been asked by the user pressing the new file button on the UI
|
|
864
|
-
"""
|
|
865
|
-
self.new_file_sig.emit(status)
|
|
866
|
-
|