pymodaq 4.2.4__py3-none-any.whl → 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +30 -23
- pymodaq/control_modules/daq_move.py +27 -14
- pymodaq/control_modules/daq_move_ui.py +28 -12
- pymodaq/control_modules/daq_viewer.py +38 -28
- pymodaq/control_modules/daq_viewer_ui.py +6 -6
- pymodaq/control_modules/mocks.py +1 -1
- pymodaq/control_modules/move_utility_classes.py +19 -10
- pymodaq/control_modules/utils.py +18 -12
- pymodaq/control_modules/viewer_utility_classes.py +13 -4
- pymodaq/dashboard.py +164 -115
- pymodaq/examples/custom_app.py +13 -16
- pymodaq/examples/custom_viewer.py +6 -6
- pymodaq/examples/function_plotter.py +13 -12
- pymodaq/examples/parameter_ex.py +50 -25
- pymodaq/examples/tcp_client.py +1 -1
- pymodaq/extensions/__init__.py +1 -1
- pymodaq/extensions/bayesian/bayesian_optimisation.py +15 -12
- pymodaq/extensions/bayesian/utils.py +10 -10
- pymodaq/extensions/console.py +10 -13
- pymodaq/extensions/{daq_logger.py → daq_logger/daq_logger.py} +36 -56
- 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 +153 -247
- pymodaq/extensions/daq_scan_ui.py +11 -9
- pymodaq/extensions/h5browser.py +8 -8
- pymodaq/extensions/pid/__init__.py +6 -3
- pymodaq/extensions/pid/daq_move_PID.py +4 -2
- pymodaq/extensions/pid/pid_controller.py +15 -12
- pymodaq/extensions/pid/utils.py +10 -5
- pymodaq/extensions/utils.py +5 -3
- pymodaq/post_treatment/load_and_plot.py +10 -7
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/utils/array_manipulation.py +4 -384
- pymodaq/utils/calibration_camera.py +12 -9
- pymodaq/utils/chrono_timer.py +7 -5
- pymodaq/utils/config.py +3 -450
- pymodaq/utils/daq_utils.py +6 -708
- pymodaq/utils/data.py +9 -2774
- pymodaq/utils/exceptions.py +0 -4
- pymodaq/utils/gui_utils/__init__.py +8 -8
- pymodaq/utils/gui_utils/loader_utils.py +38 -0
- pymodaq/utils/gui_utils/utils.py +6 -138
- pymodaq/utils/h5modules/__init__.py +0 -4
- pymodaq/utils/h5modules/module_saving.py +15 -8
- pymodaq/utils/leco/__init__.py +2 -2
- pymodaq/utils/leco/daq_move_LECODirector.py +2 -2
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +2 -2
- pymodaq/utils/leco/director_utils.py +2 -2
- pymodaq/utils/leco/leco_director.py +3 -3
- pymodaq/utils/leco/pymodaq_listener.py +2 -2
- pymodaq/utils/leco/utils.py +1 -1
- pymodaq/utils/logger.py +4 -76
- pymodaq/utils/managers/batchscan_manager.py +16 -19
- pymodaq/utils/managers/modules_manager.py +10 -7
- pymodaq/utils/managers/overshoot_manager.py +3 -5
- pymodaq/utils/managers/preset_manager.py +37 -15
- pymodaq/utils/managers/preset_manager_utils.py +11 -9
- pymodaq/utils/managers/remote_manager.py +12 -10
- pymodaq/utils/math_utils.py +4 -572
- pymodaq/utils/parameter/__init__.py +4 -11
- pymodaq/utils/parameter/utils.py +4 -299
- 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/serializer.py +64 -16
- pymodaq/utils/tcp_ip/tcp_server_client.py +10 -8
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/METADATA +5 -3
- pymodaq-5.0.0.dist-info/RECORD +123 -0
- 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/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/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/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/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 -234
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +0 -127150
- pymodaq/resources/QtDesigner_Ressources/icons.svg +0 -142
- pymodaq/resources/VERSION +0 -1
- pymodaq/resources/config_template.toml +0 -94
- 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/enums.py +0 -76
- 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 -93
- 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/lcd.py +0 -111
- 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 -102
- pymodaq/utils/h5modules/backends.py +0 -1022
- pymodaq/utils/h5modules/browsing.py +0 -625
- pymodaq/utils/h5modules/data_saving.py +0 -1105
- 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 -282
- pymodaq/utils/managers/roi_manager.py +0 -726
- pymodaq/utils/messenger.py +0 -66
- pymodaq/utils/parameter/ioxml.py +0 -542
- 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 -145
- 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 -274
- 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.2.4.dist-info/RECORD +0 -438
- /pymodaq/{post_treatment/daq_analysis → extensions/daq_logger}/__init__.py +0 -0
- /pymodaq/{utils/abstract/logger.py → extensions/daq_logger/abstract.py} +0 -0
- /pymodaq/{resources/QtDesigner_Ressources → extensions/daq_logger/db}/__init__.py +0 -0
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/WHEEL +0 -0
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/entry_points.txt +0 -0
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,1105 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created the 21/11/2022
|
|
4
|
-
|
|
5
|
-
@author: Sebastien Weber
|
|
6
|
-
"""
|
|
7
|
-
from time import time
|
|
8
|
-
from typing import Union, List, Tuple, Iterable
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
|
|
11
|
-
import numpy as np
|
|
12
|
-
|
|
13
|
-
from pymodaq.utils.abstract import ABCMeta, abstract_attribute
|
|
14
|
-
from pymodaq.utils.enums import enum_checker
|
|
15
|
-
from pymodaq.utils.data import (Axis, DataDim, DataWithAxes, DataToExport, DataDistribution,
|
|
16
|
-
DataDimError, squeeze)
|
|
17
|
-
from .saving import DataType, H5Saver
|
|
18
|
-
from .backends import GROUP, CARRAY, Node, EARRAY, NodeError
|
|
19
|
-
from pymodaq.utils.daq_utils import capitalize
|
|
20
|
-
from pymodaq.utils.scanner.utils import ScanType
|
|
21
|
-
|
|
22
|
-
SPECIAL_GROUP_NAMES = dict(nav_axes='NavAxes')
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class AxisError(Exception):
|
|
26
|
-
pass
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class DataManagement(metaclass=ABCMeta):
|
|
30
|
-
"""Base abstract class to be used for all specialized object saving and loading data to/from a h5file
|
|
31
|
-
|
|
32
|
-
Attributes
|
|
33
|
-
----------
|
|
34
|
-
data_type: DataType
|
|
35
|
-
The enum for this type of data, here abstract and should be redefined
|
|
36
|
-
"""
|
|
37
|
-
data_type: DataType = abstract_attribute()
|
|
38
|
-
_h5saver: H5Saver = abstract_attribute()
|
|
39
|
-
|
|
40
|
-
@classmethod
|
|
41
|
-
def _format_node_name(cls, ind: int) -> str:
|
|
42
|
-
""" Format the saved node following the data_type attribute and an integer index
|
|
43
|
-
|
|
44
|
-
Parameters
|
|
45
|
-
----------
|
|
46
|
-
ind: int
|
|
47
|
-
|
|
48
|
-
Returns
|
|
49
|
-
-------
|
|
50
|
-
str: the future name of the node
|
|
51
|
-
"""
|
|
52
|
-
return f'{capitalize(cls.data_type.value)}{ind:02d}'
|
|
53
|
-
|
|
54
|
-
def __enter__(self):
|
|
55
|
-
return self
|
|
56
|
-
|
|
57
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
58
|
-
self.close_file()
|
|
59
|
-
|
|
60
|
-
def close_file(self):
|
|
61
|
-
self._h5saver.close_file()
|
|
62
|
-
|
|
63
|
-
def _get_next_node_name(self, where: Union[str, Node]) -> str:
|
|
64
|
-
"""Get the formatted next node name given the ones already saved
|
|
65
|
-
|
|
66
|
-
Parameters
|
|
67
|
-
----------
|
|
68
|
-
where: Union[Node, str]
|
|
69
|
-
the path of a given node or the node itself
|
|
70
|
-
|
|
71
|
-
Returns
|
|
72
|
-
-------
|
|
73
|
-
str: the future name of the node
|
|
74
|
-
"""
|
|
75
|
-
return self._format_node_name(self._get_next_data_type_index_in_group(where))
|
|
76
|
-
|
|
77
|
-
def get_last_node_name(self, where: Union[str, Node]) -> Union[str, None]:
|
|
78
|
-
"""Get the last node name among the ones already saved
|
|
79
|
-
|
|
80
|
-
Parameters
|
|
81
|
-
----------
|
|
82
|
-
where: Union[Node, str]
|
|
83
|
-
the path of a given node or the node itself
|
|
84
|
-
|
|
85
|
-
Returns
|
|
86
|
-
-------
|
|
87
|
-
str: the name of the last saved node or None if none saved
|
|
88
|
-
"""
|
|
89
|
-
index = self._get_next_data_type_index_in_group(where) - 1
|
|
90
|
-
if index == -1:
|
|
91
|
-
return None
|
|
92
|
-
else:
|
|
93
|
-
return self._format_node_name(index)
|
|
94
|
-
|
|
95
|
-
def get_node_from_index(self, where: Union[str, Node], index: int) -> Node:
|
|
96
|
-
return self._h5saver.get_node(where, self._format_node_name(index))
|
|
97
|
-
|
|
98
|
-
def get_index_from_node_name(self, where: Union[str, Node]):
|
|
99
|
-
node = self._h5saver.get_node(where)
|
|
100
|
-
try:
|
|
101
|
-
index = int(node.name.split(self.data_type.value)[1])
|
|
102
|
-
except IndexError:
|
|
103
|
-
return None
|
|
104
|
-
return index
|
|
105
|
-
|
|
106
|
-
def _get_next_data_type_index_in_group(self, where: Union[Node, str]) -> int:
|
|
107
|
-
"""Check how much node with a given data_type are already present within the GROUP where
|
|
108
|
-
Parameters
|
|
109
|
-
----------
|
|
110
|
-
where: Union[Node, str]
|
|
111
|
-
the path of a given node or the node itself
|
|
112
|
-
|
|
113
|
-
Returns
|
|
114
|
-
-------
|
|
115
|
-
int: the next available integer to index the node name
|
|
116
|
-
"""
|
|
117
|
-
ind = 0
|
|
118
|
-
for node in self._h5saver.walk_nodes(where):
|
|
119
|
-
if 'data_type' in node.attrs:
|
|
120
|
-
if node.attrs['data_type'] == self.data_type.name:
|
|
121
|
-
ind += 1
|
|
122
|
-
return ind
|
|
123
|
-
|
|
124
|
-
def _is_node_of_data_type(self, where: Union[str, Node]) -> bool:
|
|
125
|
-
"""Check if a given node is of the data_type of the real class implementation
|
|
126
|
-
|
|
127
|
-
eg 'axis' for the AxisSaverLoader
|
|
128
|
-
|
|
129
|
-
Parameters
|
|
130
|
-
----------
|
|
131
|
-
where: Union[Node, str]
|
|
132
|
-
the path of a given node or the node itself
|
|
133
|
-
|
|
134
|
-
Returns
|
|
135
|
-
-------
|
|
136
|
-
bool
|
|
137
|
-
"""
|
|
138
|
-
node = self._get_node(where)
|
|
139
|
-
return 'data_type' in node.attrs and node.attrs['data_type'] == self.data_type
|
|
140
|
-
|
|
141
|
-
def _get_node(self, where: Union[str, Node]) -> Node:
|
|
142
|
-
"""Utility method to get a node from a node or a string"""
|
|
143
|
-
return self._h5saver.get_node(where)
|
|
144
|
-
|
|
145
|
-
def _get_nodes(self, where: Union[str, Node]) -> List[Node]:
|
|
146
|
-
"""Get Nodes hanging from where including where
|
|
147
|
-
|
|
148
|
-
Parameters
|
|
149
|
-
----------
|
|
150
|
-
where: Union[Node, str]
|
|
151
|
-
the path of a given node or the node itself
|
|
152
|
-
|
|
153
|
-
Returns
|
|
154
|
-
-------
|
|
155
|
-
List[Node]
|
|
156
|
-
"""
|
|
157
|
-
node = self._get_node(where)
|
|
158
|
-
if isinstance(node, GROUP):
|
|
159
|
-
return [child_node for child_node in self._h5saver.walk_nodes(node)]
|
|
160
|
-
else:
|
|
161
|
-
return [node]
|
|
162
|
-
|
|
163
|
-
def _get_nodes_from_data_type(self, where: Union[str, Node]) -> List[Node]:
|
|
164
|
-
"""Get the node list hanging from a parent and having the same data type as self
|
|
165
|
-
|
|
166
|
-
Parameters
|
|
167
|
-
----------
|
|
168
|
-
where: Union[Node, str]
|
|
169
|
-
the path of a given node
|
|
170
|
-
|
|
171
|
-
Returns
|
|
172
|
-
-------
|
|
173
|
-
list of Nodes
|
|
174
|
-
"""
|
|
175
|
-
node = self._get_node(where)
|
|
176
|
-
if isinstance(node, GROUP):
|
|
177
|
-
parent_node = node
|
|
178
|
-
else:
|
|
179
|
-
parent_node = node.parent_node
|
|
180
|
-
|
|
181
|
-
nodes = []
|
|
182
|
-
for child_node in self._h5saver.walk_nodes(parent_node):
|
|
183
|
-
if self._is_node_of_data_type(child_node):
|
|
184
|
-
nodes.append(child_node)
|
|
185
|
-
return nodes
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
class AxisSaverLoader(DataManagement):
|
|
189
|
-
"""Specialized Object to save and load Axis object to and from a h5file
|
|
190
|
-
|
|
191
|
-
Parameters
|
|
192
|
-
----------
|
|
193
|
-
h5saver: H5Saver
|
|
194
|
-
|
|
195
|
-
Attributes
|
|
196
|
-
----------
|
|
197
|
-
data_type: DataType
|
|
198
|
-
The enum for this type of data, here 'axis'
|
|
199
|
-
"""
|
|
200
|
-
data_type = DataType['axis']
|
|
201
|
-
|
|
202
|
-
def __init__(self, h5saver: H5Saver):
|
|
203
|
-
self._h5saver = h5saver
|
|
204
|
-
self.data_type = enum_checker(DataType, self.data_type)
|
|
205
|
-
|
|
206
|
-
def add_axis(self, where: Union[Node, str], axis: Axis, enlargeable=False):
|
|
207
|
-
"""Write Axis info at a given position within a h5 file
|
|
208
|
-
|
|
209
|
-
Parameters
|
|
210
|
-
----------
|
|
211
|
-
where: Union[Node, str]
|
|
212
|
-
the path of a given node or the node itself
|
|
213
|
-
axis: Axis
|
|
214
|
-
the Axis object to add as a node in the h5file
|
|
215
|
-
enlargeable: bool
|
|
216
|
-
Specify if the underlying array will be enlargebale
|
|
217
|
-
"""
|
|
218
|
-
array = self._h5saver.add_array(where, self._get_next_node_name(where), self.data_type, title=axis.label,
|
|
219
|
-
array_to_save=axis.get_data(), data_dimension=DataDim['Data1D'],
|
|
220
|
-
enlargeable=enlargeable,
|
|
221
|
-
metadata=dict(size=axis.size, label=axis.label, units=axis.units,
|
|
222
|
-
index=axis.index, offset=axis.offset, scaling=axis.scaling,
|
|
223
|
-
distribution='uniform' if axis.is_axis_linear() else 'spread',
|
|
224
|
-
spread_order=axis.spread_order))
|
|
225
|
-
return array
|
|
226
|
-
|
|
227
|
-
def load_axis(self, where: Union[Node, str]) -> Axis:
|
|
228
|
-
"""create an Axis object from the data and metadata at a given node if of data_type: 'axis
|
|
229
|
-
|
|
230
|
-
Parameters
|
|
231
|
-
----------
|
|
232
|
-
where: Union[Node, str]
|
|
233
|
-
the path of a given node or the node itself
|
|
234
|
-
|
|
235
|
-
Returns
|
|
236
|
-
-------
|
|
237
|
-
Axis
|
|
238
|
-
"""
|
|
239
|
-
axis_node = self._get_node(where)
|
|
240
|
-
if not self._is_node_of_data_type(axis_node):
|
|
241
|
-
raise AxisError(f'Could not create an Axis object from this node: {axis_node}')
|
|
242
|
-
return Axis(label=axis_node.attrs['label'], units=axis_node.attrs['units'],
|
|
243
|
-
data=squeeze(axis_node.read()), index=axis_node.attrs['index'],
|
|
244
|
-
spread_order=axis_node.attrs['spread_order'])
|
|
245
|
-
|
|
246
|
-
def get_axes(self, where: Union[Node, str]) -> List[Axis]:
|
|
247
|
-
"""Return a list of Axis objects from the Axis Nodes hanging from (or among) a given Node
|
|
248
|
-
|
|
249
|
-
Parameters
|
|
250
|
-
----------
|
|
251
|
-
where: Union[Node, str]
|
|
252
|
-
the path of a given node or the node itself
|
|
253
|
-
|
|
254
|
-
Returns
|
|
255
|
-
-------
|
|
256
|
-
List[Axis]: the list of all Axis object
|
|
257
|
-
"""
|
|
258
|
-
axes = []
|
|
259
|
-
for node in self._get_nodes_from_data_type(where):
|
|
260
|
-
axis = self.load_axis(node)
|
|
261
|
-
# if axis.size > 1:
|
|
262
|
-
# axes.append(axis)
|
|
263
|
-
axes.append(axis)
|
|
264
|
-
return axes
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
class DataSaverLoader(DataManagement):
|
|
268
|
-
"""Specialized Object to save and load DataWithAxes object to and from a h5file
|
|
269
|
-
|
|
270
|
-
Parameters
|
|
271
|
-
----------
|
|
272
|
-
h5saver: H5Saver or Path or str
|
|
273
|
-
|
|
274
|
-
Attributes
|
|
275
|
-
----------
|
|
276
|
-
data_type: DataType
|
|
277
|
-
The enum for this type of data, here 'data'
|
|
278
|
-
"""
|
|
279
|
-
data_type = DataType['data']
|
|
280
|
-
|
|
281
|
-
def __init__(self, h5saver: Union[H5Saver, Path]):
|
|
282
|
-
self.data_type = enum_checker(DataType, self.data_type)
|
|
283
|
-
|
|
284
|
-
if isinstance(h5saver, Path) or isinstance(h5saver, str):
|
|
285
|
-
h5saver_tmp = H5Saver()
|
|
286
|
-
h5saver_tmp.init_file(addhoc_file_path=Path(h5saver))
|
|
287
|
-
h5saver = h5saver_tmp
|
|
288
|
-
|
|
289
|
-
self._h5saver = h5saver
|
|
290
|
-
self._axis_saver = AxisSaverLoader(h5saver)
|
|
291
|
-
if not isinstance(self, ErrorSaverLoader):
|
|
292
|
-
self._error_saver = ErrorSaverLoader(h5saver)
|
|
293
|
-
|
|
294
|
-
def isopen(self) -> bool:
|
|
295
|
-
""" Get the opened status of the underlying hdf5 file"""
|
|
296
|
-
return self._h5saver.isopen()
|
|
297
|
-
|
|
298
|
-
def add_data(self, where: Union[Node, str], data: DataWithAxes, save_axes=True, **kwargs):
|
|
299
|
-
"""Adds Array nodes to a given location adding eventually axes as others nodes and metadata
|
|
300
|
-
|
|
301
|
-
Parameters
|
|
302
|
-
----------
|
|
303
|
-
where: Union[Node, str]
|
|
304
|
-
the path of a given node or the node itself
|
|
305
|
-
data: DataWithAxes
|
|
306
|
-
save_axes: bool
|
|
307
|
-
"""
|
|
308
|
-
|
|
309
|
-
for ind_data in range(len(data)):
|
|
310
|
-
metadata = dict(timestamp=data.timestamp, label=data.labels[ind_data],
|
|
311
|
-
source=data.source.name, distribution=data.distribution.name,
|
|
312
|
-
origin=data.origin,
|
|
313
|
-
nav_indexes=tuple(data.nav_indexes)
|
|
314
|
-
if data.nav_indexes is not None else None,)
|
|
315
|
-
for name in data.extra_attributes:
|
|
316
|
-
metadata[name] = getattr(data, name)
|
|
317
|
-
self._h5saver.add_array(where, self._get_next_node_name(where), self.data_type,
|
|
318
|
-
title=data.name, array_to_save=data[ind_data],
|
|
319
|
-
data_dimension=data.dim.name, metadata=metadata)
|
|
320
|
-
|
|
321
|
-
if save_axes:
|
|
322
|
-
for axis in data.axes:
|
|
323
|
-
self._axis_saver.add_axis(where, axis)
|
|
324
|
-
|
|
325
|
-
if data.errors is not None:
|
|
326
|
-
self._error_saver.add_data(where, data.errors_as_dwa(), save_axes=False)
|
|
327
|
-
|
|
328
|
-
def get_axes(self, where: Union[Node, str]) -> List[Axis]:
|
|
329
|
-
"""
|
|
330
|
-
|
|
331
|
-
Parameters
|
|
332
|
-
----------
|
|
333
|
-
where: Union[Node, str]
|
|
334
|
-
the path of a given node or the node itself
|
|
335
|
-
|
|
336
|
-
Returns
|
|
337
|
-
-------
|
|
338
|
-
|
|
339
|
-
"""
|
|
340
|
-
return self._axis_saver.get_axes(where)
|
|
341
|
-
|
|
342
|
-
def get_bkg_nodes(self, where: Union[Node, str]):
|
|
343
|
-
bkg_nodes = []
|
|
344
|
-
for node in self._h5saver.walk_nodes(where):
|
|
345
|
-
if 'data_type' in node.attrs and node.attrs['data_type'] == 'bkg':
|
|
346
|
-
bkg_nodes.append(node)
|
|
347
|
-
return bkg_nodes
|
|
348
|
-
|
|
349
|
-
def get_data_arrays(self, where: Union[Node, str], with_bkg=False,
|
|
350
|
-
load_all=False) -> List[np.ndarray]:
|
|
351
|
-
"""
|
|
352
|
-
|
|
353
|
-
Parameters
|
|
354
|
-
----------
|
|
355
|
-
where: Union[Node, str]
|
|
356
|
-
the path of a given node or the node itself
|
|
357
|
-
with_bkg: bool
|
|
358
|
-
If True try to load background node and return the array with background subtraction
|
|
359
|
-
load_all: bool
|
|
360
|
-
If True load all similar nodes hanging from a parent
|
|
361
|
-
|
|
362
|
-
Returns
|
|
363
|
-
-------
|
|
364
|
-
list of ndarray
|
|
365
|
-
"""
|
|
366
|
-
where = self._get_node(where)
|
|
367
|
-
if with_bkg:
|
|
368
|
-
bkg_nodes = []
|
|
369
|
-
if with_bkg:
|
|
370
|
-
bkg_nodes = self.get_bkg_nodes(where.parent_node)
|
|
371
|
-
if len(bkg_nodes) == 0:
|
|
372
|
-
with_bkg = False
|
|
373
|
-
|
|
374
|
-
if load_all:
|
|
375
|
-
getter = self._get_nodes_from_data_type
|
|
376
|
-
else:
|
|
377
|
-
getter = self._get_nodes
|
|
378
|
-
|
|
379
|
-
if with_bkg:
|
|
380
|
-
return [squeeze(array.read()-bkg.read(),
|
|
381
|
-
squeeze_indexes=self._get_signal_indexes_to_squeeze(array))
|
|
382
|
-
for array, bkg in zip(getter(where), bkg_nodes)]
|
|
383
|
-
else:
|
|
384
|
-
return [squeeze(array.read(),
|
|
385
|
-
squeeze_indexes=self._get_signal_indexes_to_squeeze(array))
|
|
386
|
-
for array in getter(where)]
|
|
387
|
-
|
|
388
|
-
def _get_signal_indexes_to_squeeze(self, array: Union[CARRAY, EARRAY]):
|
|
389
|
-
""" Get the tuple of indexes in the array shape that are not navigation and should be
|
|
390
|
-
squeezed"""
|
|
391
|
-
sig_indexes = []
|
|
392
|
-
for ind in range(len(array.attrs['shape'])):
|
|
393
|
-
if ind not in array.attrs['nav_indexes'] and array.attrs['shape'][ind] == 1:
|
|
394
|
-
sig_indexes.append(ind)
|
|
395
|
-
return tuple(sig_indexes)
|
|
396
|
-
|
|
397
|
-
def load_data(self, where, with_bkg=False, load_all=False) -> DataWithAxes:
|
|
398
|
-
"""Return a DataWithAxes object from the Data and Axis Nodes hanging from (or among) a
|
|
399
|
-
given Node
|
|
400
|
-
|
|
401
|
-
Does not include navigation axes stored elsewhere in the h5file. The node path is stored in
|
|
402
|
-
the DatWithAxis using the attribute path
|
|
403
|
-
|
|
404
|
-
Parameters
|
|
405
|
-
----------
|
|
406
|
-
where: Union[Node, str]
|
|
407
|
-
the path of a given node or the node itself
|
|
408
|
-
with_bkg: bool
|
|
409
|
-
If True try to load background node and return the data with background subtraction
|
|
410
|
-
load_all: bool
|
|
411
|
-
If True, will load all data hanging from the same parent node
|
|
412
|
-
|
|
413
|
-
See Also
|
|
414
|
-
--------
|
|
415
|
-
load_data
|
|
416
|
-
"""
|
|
417
|
-
|
|
418
|
-
data_node = self._get_node(where)
|
|
419
|
-
|
|
420
|
-
if load_all:
|
|
421
|
-
parent_node = data_node.parent_node
|
|
422
|
-
data_nodes = self._get_nodes_from_data_type(parent_node)
|
|
423
|
-
data_node = data_nodes[0]
|
|
424
|
-
error_node = data_node
|
|
425
|
-
else:
|
|
426
|
-
parent_node = data_node.parent_node
|
|
427
|
-
if not isinstance(data_node, CARRAY):
|
|
428
|
-
return
|
|
429
|
-
data_nodes = [data_node]
|
|
430
|
-
error_node = None
|
|
431
|
-
try:
|
|
432
|
-
error_node_index = self.get_index_from_node_name(data_node)
|
|
433
|
-
if error_node_index is not None:
|
|
434
|
-
error_node = self._error_saver.get_node_from_index(parent_node, error_node_index)
|
|
435
|
-
except NodeError as e:
|
|
436
|
-
pass
|
|
437
|
-
|
|
438
|
-
if 'axis' in self.data_type.name:
|
|
439
|
-
ndarrays = [squeeze(data_node.read()) for data_node in data_nodes]
|
|
440
|
-
axes = [Axis(label=data_node.attrs['label'], units=data_node.attrs['units'],
|
|
441
|
-
data=np.linspace(0, ndarrays[0].size-1, ndarrays[0].size-1))]
|
|
442
|
-
error_arrays = None
|
|
443
|
-
else:
|
|
444
|
-
ndarrays = self.get_data_arrays(data_node, with_bkg=with_bkg, load_all=load_all)
|
|
445
|
-
axes = self.get_axes(parent_node)
|
|
446
|
-
if error_node is not None:
|
|
447
|
-
error_arrays = self._error_saver.get_data_arrays(error_node, load_all=load_all)
|
|
448
|
-
if len(error_arrays) == 0:
|
|
449
|
-
error_arrays = None
|
|
450
|
-
else:
|
|
451
|
-
error_arrays = None
|
|
452
|
-
|
|
453
|
-
extra_attributes = data_node.attrs.to_dict()
|
|
454
|
-
for name in ['TITLE', 'CLASS', 'VERSION', 'backend', 'source', 'data_dimension',
|
|
455
|
-
'distribution', 'label', 'origin', 'nav_indexes', 'dtype', 'data_type',
|
|
456
|
-
'subdtype', 'shape', 'size', 'EXTDIM', 'path', 'timestamp']:
|
|
457
|
-
extra_attributes.pop(name, None)
|
|
458
|
-
|
|
459
|
-
data = DataWithAxes(data_node.attrs['TITLE'],
|
|
460
|
-
source=data_node.attrs['source'] if 'source' in data_node.attrs
|
|
461
|
-
else 'raw',
|
|
462
|
-
dim=data_node.attrs['data_dimension'],
|
|
463
|
-
distribution=data_node.attrs['distribution'],
|
|
464
|
-
data=ndarrays,
|
|
465
|
-
labels=[node.attrs['label'] for node in data_nodes],
|
|
466
|
-
origin=data_node.attrs['origin'] if 'origin' in data_node.attrs else '',
|
|
467
|
-
nav_indexes=data_node.attrs['nav_indexes'] if 'nav_indexes' in
|
|
468
|
-
data_node.attrs else (),
|
|
469
|
-
axes=axes,
|
|
470
|
-
errors=error_arrays,
|
|
471
|
-
path=data_node.path,
|
|
472
|
-
**extra_attributes)
|
|
473
|
-
if 'axis' not in self.data_type.name:
|
|
474
|
-
data.timestamp = data_node.attrs['timestamp']
|
|
475
|
-
return data
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
class BkgSaver(DataSaverLoader):
|
|
479
|
-
"""Specialized Object to save and load DataWithAxes background object to and from a h5file
|
|
480
|
-
|
|
481
|
-
Parameters
|
|
482
|
-
----------
|
|
483
|
-
hsaver: H5Saver
|
|
484
|
-
|
|
485
|
-
Attributes
|
|
486
|
-
----------
|
|
487
|
-
data_type: DataType
|
|
488
|
-
The enum for this type of data, here 'bkg'
|
|
489
|
-
"""
|
|
490
|
-
data_type = DataType['bkg']
|
|
491
|
-
|
|
492
|
-
def __init__(self, h5saver: H5Saver):
|
|
493
|
-
super().__init__(h5saver)
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
class ErrorSaverLoader(DataSaverLoader):
|
|
497
|
-
"""Specialized Object to save and load DataWithAxes errors bars to and from a h5file
|
|
498
|
-
|
|
499
|
-
Parameters
|
|
500
|
-
----------
|
|
501
|
-
hsaver: H5Saver
|
|
502
|
-
|
|
503
|
-
Attributes
|
|
504
|
-
----------
|
|
505
|
-
data_type: DataType
|
|
506
|
-
The enum for this type of data, here 'error'
|
|
507
|
-
"""
|
|
508
|
-
data_type = DataType['error']
|
|
509
|
-
|
|
510
|
-
def __init__(self, h5saver: H5Saver):
|
|
511
|
-
super().__init__(h5saver)
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
class DataEnlargeableSaver(DataSaverLoader):
|
|
515
|
-
""" Specialized Object to save and load enlargeable DataWithAxes saved object to and from a
|
|
516
|
-
h5file
|
|
517
|
-
|
|
518
|
-
Particular case of DataND with a single *nav_indexes* parameter will be appended as chunks
|
|
519
|
-
of signal data
|
|
520
|
-
|
|
521
|
-
Parameters
|
|
522
|
-
----------
|
|
523
|
-
h5saver: H5Saver
|
|
524
|
-
|
|
525
|
-
Attributes
|
|
526
|
-
----------
|
|
527
|
-
data_type: DataType
|
|
528
|
-
The enum for this type of data, here 'data_enlargeable'
|
|
529
|
-
|
|
530
|
-
Notes
|
|
531
|
-
-----
|
|
532
|
-
To be used to save data from a timed logger (DAQViewer continuous saving or DAQLogger extension) or from an
|
|
533
|
-
adaptive scan where the final shape is unknown or other module that need this feature
|
|
534
|
-
"""
|
|
535
|
-
data_type = DataType['data_enlargeable']
|
|
536
|
-
|
|
537
|
-
def __init__(self, h5saver: Union[H5Saver, Path],
|
|
538
|
-
enl_axis_names: Iterable[str] = ('nav axis',),
|
|
539
|
-
enl_axis_units: Iterable[str] = ('',)):
|
|
540
|
-
super().__init__(h5saver)
|
|
541
|
-
|
|
542
|
-
self._n_enl_axes = len(enl_axis_names)
|
|
543
|
-
self._enl_axis_names = enl_axis_names
|
|
544
|
-
self._enl_axis_units = enl_axis_units
|
|
545
|
-
|
|
546
|
-
def _create_data_arrays(self, where: Union[Node, str], data: DataWithAxes, save_axes=True,
|
|
547
|
-
add_enl_axes=True):
|
|
548
|
-
""" Create enlargeable array to store data
|
|
549
|
-
|
|
550
|
-
Parameters
|
|
551
|
-
----------
|
|
552
|
-
where: Union[Node, str]
|
|
553
|
-
the path of a given node or the node itself
|
|
554
|
-
data: DataWithAxes
|
|
555
|
-
save_axes: bool
|
|
556
|
-
if True, will save signal axes as data nodes
|
|
557
|
-
add_enl_axes: bool
|
|
558
|
-
if True, will save enlargeable axes as data nodes (depending on the self._enl_axis_names
|
|
559
|
-
field)
|
|
560
|
-
|
|
561
|
-
Notes
|
|
562
|
-
-----
|
|
563
|
-
Because data will be saved at a given index in the enlargeable array, related signal axes
|
|
564
|
-
will have their index increased by 1)
|
|
565
|
-
"""
|
|
566
|
-
|
|
567
|
-
if self.get_last_node_name(where) is None:
|
|
568
|
-
for ind_data in range(len(data)):
|
|
569
|
-
nav_indexes = list(data.nav_indexes)
|
|
570
|
-
nav_indexes = ([0] +
|
|
571
|
-
list(np.array(nav_indexes, dtype=int) + 1))
|
|
572
|
-
|
|
573
|
-
self._h5saver.add_array(where, self._get_next_node_name(where), self.data_type,
|
|
574
|
-
title=data.name,
|
|
575
|
-
array_to_save=data[ind_data],
|
|
576
|
-
data_shape=data[ind_data].shape,
|
|
577
|
-
array_type=data[ind_data].dtype,
|
|
578
|
-
enlargeable=True,
|
|
579
|
-
data_dimension=data.dim.name,
|
|
580
|
-
metadata=dict(timestamp=data.timestamp,
|
|
581
|
-
label=data.labels[ind_data],
|
|
582
|
-
source=data.source.name,
|
|
583
|
-
distribution='spread',
|
|
584
|
-
origin=data.origin,
|
|
585
|
-
nav_indexes=tuple(nav_indexes)))
|
|
586
|
-
if add_enl_axes:
|
|
587
|
-
for ind_enl_axis in range(self._n_enl_axes):
|
|
588
|
-
self._axis_saver.add_axis(where,
|
|
589
|
-
Axis(self._enl_axis_names[ind_enl_axis],
|
|
590
|
-
self._enl_axis_units[ind_enl_axis],
|
|
591
|
-
data=np.array([0., 1.]),
|
|
592
|
-
index=0, spread_order=ind_enl_axis),
|
|
593
|
-
enlargeable=True)
|
|
594
|
-
if save_axes:
|
|
595
|
-
for axis in data.axes:
|
|
596
|
-
axis = axis.copy()
|
|
597
|
-
axis.index += 1 # because of enlargeable data will have an extra shape
|
|
598
|
-
self._axis_saver.add_axis(where, axis)
|
|
599
|
-
|
|
600
|
-
def add_data(self, where: Union[Node, str], data: DataWithAxes,
|
|
601
|
-
axis_values: Iterable[float] = None):
|
|
602
|
-
""" Append data to an enlargeable array node
|
|
603
|
-
|
|
604
|
-
Data of dim (0, 1 or 2) will be just appended to the enlargeable array.
|
|
605
|
-
|
|
606
|
-
Uniform DataND with one navigation axis of length (Lnav) will be considered as a collection
|
|
607
|
-
of Lnav signal data of dim (0, 1 or 2) and will therefore be appended as Lnav signal data
|
|
608
|
-
|
|
609
|
-
Parameters
|
|
610
|
-
----------
|
|
611
|
-
where: Union[Node, str]
|
|
612
|
-
the path of a given node or the node itself
|
|
613
|
-
data: DataWithAxes
|
|
614
|
-
axis_values: optional, list of floats
|
|
615
|
-
the new spread axis values added to the data
|
|
616
|
-
if None the axes are not added to the h5 file
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
"""
|
|
620
|
-
add_enl_axes = axis_values is not None
|
|
621
|
-
|
|
622
|
-
if self.get_last_node_name(where) is None:
|
|
623
|
-
if len(data.nav_indexes) == 0:
|
|
624
|
-
data_init = data
|
|
625
|
-
else:
|
|
626
|
-
raise DataDimError('It is not possible to append DataND')
|
|
627
|
-
self._create_data_arrays(where, data_init, save_axes=True, add_enl_axes=add_enl_axes)
|
|
628
|
-
|
|
629
|
-
for ind_data in range(len(data)):
|
|
630
|
-
array: EARRAY = self.get_node_from_index(where, ind_data)
|
|
631
|
-
array.append(data[ind_data])
|
|
632
|
-
if add_enl_axes and axis_values is not None:
|
|
633
|
-
for ind_axis in range(self._n_enl_axes):
|
|
634
|
-
axis_array: EARRAY = self._axis_saver.get_node_from_index(where, ind_axis)
|
|
635
|
-
axis_array.append(np.array([axis_values[ind_axis]]))
|
|
636
|
-
axis_array.attrs['size'] += 1
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
class DataExtendedSaver(DataSaverLoader):
|
|
640
|
-
"""Specialized Object to save and load DataWithAxes saved object to and from a h5file in extended arrays
|
|
641
|
-
|
|
642
|
-
Parameters
|
|
643
|
-
----------
|
|
644
|
-
h5saver: H5Saver
|
|
645
|
-
extended_shape: Tuple[int]
|
|
646
|
-
the extra shape compared to the data the h5array will have
|
|
647
|
-
|
|
648
|
-
Attributes
|
|
649
|
-
----------
|
|
650
|
-
data_type: DataType
|
|
651
|
-
The enum for this type of data, here 'data'
|
|
652
|
-
"""
|
|
653
|
-
data_type = DataType['data']
|
|
654
|
-
|
|
655
|
-
def __init__(self, h5saver: H5Saver, extended_shape: Tuple[int]):
|
|
656
|
-
super().__init__(h5saver)
|
|
657
|
-
self.extended_shape = extended_shape
|
|
658
|
-
|
|
659
|
-
def _create_data_arrays(self, where: Union[Node, str], data: DataWithAxes, save_axes=True,
|
|
660
|
-
distribution=DataDistribution['uniform']):
|
|
661
|
-
""" Create array with extra dimensions (from scan) to store data
|
|
662
|
-
|
|
663
|
-
Parameters
|
|
664
|
-
----------
|
|
665
|
-
where: Union[Node, str]
|
|
666
|
-
the path of a given node or the node itself
|
|
667
|
-
data: DataWithAxes
|
|
668
|
-
save_axes: bool
|
|
669
|
-
|
|
670
|
-
Notes
|
|
671
|
-
-----
|
|
672
|
-
Because data will be saved at a given index in the "scan" array, related axes will have their index
|
|
673
|
-
increased by the length of the scan dim (1 for scan1D, 2 for scan2D, ...)
|
|
674
|
-
"""
|
|
675
|
-
if self.get_last_node_name(where) is None:
|
|
676
|
-
for ind_data in range(len(data)):
|
|
677
|
-
nav_indexes = list(data.nav_indexes)
|
|
678
|
-
nav_indexes = [ind for ind in range(len(self.extended_shape))] +\
|
|
679
|
-
list(np.array(nav_indexes, dtype=int) + len(self.extended_shape))
|
|
680
|
-
|
|
681
|
-
self._h5saver.add_array(where, self._get_next_node_name(where), self.data_type, title=data.name,
|
|
682
|
-
data_shape=data[ind_data].shape,
|
|
683
|
-
array_type=data[ind_data].dtype,
|
|
684
|
-
scan_shape=self.extended_shape,
|
|
685
|
-
add_scan_dim=True,
|
|
686
|
-
data_dimension=data.dim.name,
|
|
687
|
-
metadata=dict(timestamp=data.timestamp, label=data.labels[ind_data],
|
|
688
|
-
source=data.source.name, distribution=distribution.name,
|
|
689
|
-
origin=data.origin,
|
|
690
|
-
nav_indexes=tuple(nav_indexes)))
|
|
691
|
-
|
|
692
|
-
if save_axes:
|
|
693
|
-
for axis in data.axes:
|
|
694
|
-
axis.index += len(self.extended_shape)
|
|
695
|
-
# because there will be len(self.extended_shape) extra navigation axes
|
|
696
|
-
self._axis_saver.add_axis(where, axis)
|
|
697
|
-
|
|
698
|
-
def add_data(self, where: Union[Node, str], data: DataWithAxes, indexes: List[int],
|
|
699
|
-
distribution=DataDistribution['uniform']):
|
|
700
|
-
"""Adds given DataWithAxes at a location within the initialized h5 array
|
|
701
|
-
|
|
702
|
-
Parameters
|
|
703
|
-
----------
|
|
704
|
-
where: Union[Node, str]
|
|
705
|
-
the path of a given node or the node itself
|
|
706
|
-
data: DataWithAxes
|
|
707
|
-
indexes: Iterable[int]
|
|
708
|
-
indexes where to save data in the init h5array (should have the same length as extended_shape and with values
|
|
709
|
-
coherent with this shape
|
|
710
|
-
"""
|
|
711
|
-
if len(indexes) != len(self.extended_shape):
|
|
712
|
-
raise IndexError(f'Cannot put data into the h5array with extended indexes {indexes}')
|
|
713
|
-
for ind in range(len(indexes)):
|
|
714
|
-
if indexes[ind] > self.extended_shape[ind]:
|
|
715
|
-
raise IndexError(f'Indexes cannot be higher than the array shape')
|
|
716
|
-
|
|
717
|
-
if self.get_last_node_name(where) is None:
|
|
718
|
-
self._create_data_arrays(where, data, save_axes=True, distribution=distribution)
|
|
719
|
-
|
|
720
|
-
for ind_data in range(len(data)):
|
|
721
|
-
#todo check that getting with index is safe...
|
|
722
|
-
array: CARRAY = self.get_node_from_index(where, ind_data)
|
|
723
|
-
array[tuple(indexes)] = data[ind_data]
|
|
724
|
-
# maybe use array.__setitem__(indexes, data[ind_data]) if it's not working
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
class DataToExportSaver:
|
|
728
|
-
"""Object used to save DataToExport object into a h5file following the PyMoDAQ convention
|
|
729
|
-
|
|
730
|
-
Parameters
|
|
731
|
-
----------
|
|
732
|
-
h5saver: H5Saver
|
|
733
|
-
|
|
734
|
-
"""
|
|
735
|
-
def __init__(self, h5saver: Union[H5Saver, Path, str]):
|
|
736
|
-
if isinstance(h5saver, Path) or isinstance(h5saver, str):
|
|
737
|
-
h5saver_tmp = H5Saver()
|
|
738
|
-
h5saver_tmp.init_file(addhoc_file_path=Path(h5saver))
|
|
739
|
-
h5saver = h5saver_tmp
|
|
740
|
-
|
|
741
|
-
self._h5saver = h5saver
|
|
742
|
-
self._data_saver = DataSaverLoader(h5saver)
|
|
743
|
-
self._bkg_saver = BkgSaver(h5saver)
|
|
744
|
-
|
|
745
|
-
def _get_node(self, where: Union[Node, str]) -> Node:
|
|
746
|
-
return self._h5saver.get_node(where)
|
|
747
|
-
|
|
748
|
-
def close(self):
|
|
749
|
-
self._h5saver.close()
|
|
750
|
-
|
|
751
|
-
def close_file(self):
|
|
752
|
-
self._h5saver.close_file()
|
|
753
|
-
|
|
754
|
-
def __enter__(self):
|
|
755
|
-
return self
|
|
756
|
-
|
|
757
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
758
|
-
self.close_file()
|
|
759
|
-
|
|
760
|
-
def isopen(self) -> bool:
|
|
761
|
-
""" Get the opened status of the underlying hdf5 file"""
|
|
762
|
-
return self._h5saver.isopen()
|
|
763
|
-
|
|
764
|
-
@staticmethod
|
|
765
|
-
def channel_formatter(ind: int):
|
|
766
|
-
"""All DataWithAxes included in the DataToExport will be saved into a channel group indexed
|
|
767
|
-
and formatted as below"""
|
|
768
|
-
return f'CH{ind:02d}'
|
|
769
|
-
|
|
770
|
-
def add_data(self, where: Union[Node, str], data: DataToExport, settings_as_xml='',
|
|
771
|
-
metadata=None, **kwargs):
|
|
772
|
-
"""
|
|
773
|
-
|
|
774
|
-
Parameters
|
|
775
|
-
----------
|
|
776
|
-
where: Union[Node, str]
|
|
777
|
-
the path of a given node or the node itself
|
|
778
|
-
data: DataToExport
|
|
779
|
-
settings_as_xml: str
|
|
780
|
-
The settings parameter as an XML string
|
|
781
|
-
metadata: dict
|
|
782
|
-
all extra metadata to be saved in the group node where data will be saved
|
|
783
|
-
|
|
784
|
-
"""
|
|
785
|
-
if metadata is None:
|
|
786
|
-
metadata = {}
|
|
787
|
-
dims = data.get_dim_presents()
|
|
788
|
-
for dim in dims:
|
|
789
|
-
dim_group = self._h5saver.get_set_group(where, dim)
|
|
790
|
-
for ind, dwa in enumerate(data.get_data_from_dim(dim)):
|
|
791
|
-
# dwa: DataWithAxes filtered by dim
|
|
792
|
-
dwa_group = self._h5saver.get_set_group(dim_group, self.channel_formatter(ind),
|
|
793
|
-
dwa.name)
|
|
794
|
-
# dwa_group = self._h5saver.add_ch_group(dim_group, dwa.name)
|
|
795
|
-
self._data_saver.add_data(dwa_group, dwa, **kwargs)
|
|
796
|
-
|
|
797
|
-
def add_bkg(self, where: Union[Node, str], data: DataToExport):
|
|
798
|
-
dims = data.get_dim_presents()
|
|
799
|
-
for dim in dims:
|
|
800
|
-
dim_group = self._h5saver.get_set_group(where, dim)
|
|
801
|
-
for ind, dwa in enumerate(data.get_data_from_dim(dim)):
|
|
802
|
-
# dwa: DataWithAxes filtered by dim
|
|
803
|
-
dwa_group = self._h5saver.get_set_group(dim_group,
|
|
804
|
-
self.channel_formatter(ind), dwa.name)
|
|
805
|
-
# dwa_group = self._get_node_from_title(dim_group, dwa.name)
|
|
806
|
-
if dwa_group is not None:
|
|
807
|
-
self._bkg_saver.add_data(dwa_group, dwa, save_axes=False)
|
|
808
|
-
|
|
809
|
-
def add_error(self, where: Union[Node, str], data: DataToExport):
|
|
810
|
-
dims = data.get_dim_presents()
|
|
811
|
-
for dim in dims:
|
|
812
|
-
dim_group = self._h5saver.get_set_group(where, dim)
|
|
813
|
-
for ind, dwa in enumerate(data.get_data_from_dim(dim)):
|
|
814
|
-
# dwa: DataWithAxes filtered by dim
|
|
815
|
-
dwa_group = self._h5saver.get_set_group(dim_group,
|
|
816
|
-
self.channel_formatter(ind), dwa.name)
|
|
817
|
-
# dwa_group = self._get_node_from_title(dim_group, dwa.name)
|
|
818
|
-
if dwa_group is not None:
|
|
819
|
-
self._bkg_saver.add_data(dwa_group, dwa, save_axes=False)
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
class DataToExportEnlargeableSaver(DataToExportSaver):
|
|
823
|
-
"""Generic object to save DataToExport objects in an enlargeable h5 array
|
|
824
|
-
|
|
825
|
-
The next enlarged value should be specified in the add_data method
|
|
826
|
-
|
|
827
|
-
Parameters
|
|
828
|
-
----------
|
|
829
|
-
h5saver: H5Saver
|
|
830
|
-
enl_axis_names: Iterable[str]
|
|
831
|
-
The names of the enlargeable axis, default ['nav_axis']
|
|
832
|
-
enl_axis_units: Iterable[str]
|
|
833
|
-
The names of the enlargeable axis, default ['']
|
|
834
|
-
axis_name: str, deprecated use enl_axis_names
|
|
835
|
-
the name of the enlarged axis array
|
|
836
|
-
axis_units: str, deprecated use enl_axis_units
|
|
837
|
-
the units of the enlarged axis array
|
|
838
|
-
"""
|
|
839
|
-
def __init__(self, h5saver: H5Saver,
|
|
840
|
-
enl_axis_names: Iterable[str] = None,
|
|
841
|
-
enl_axis_units: Iterable[str] = None,
|
|
842
|
-
axis_name: str = 'nav axis', axis_units: str = ''):
|
|
843
|
-
|
|
844
|
-
super().__init__(h5saver)
|
|
845
|
-
if enl_axis_names is None: # for backcompatibility
|
|
846
|
-
enl_axis_names = (axis_name,)
|
|
847
|
-
if enl_axis_units is None: # for backcompatibilitu
|
|
848
|
-
enl_axis_units = (axis_units,)
|
|
849
|
-
|
|
850
|
-
if len(enl_axis_names) != len(enl_axis_units):
|
|
851
|
-
raise ValueError('Both enl_axis_names and enl_axis_units should have the same length')
|
|
852
|
-
|
|
853
|
-
self._enl_axis_names = enl_axis_names
|
|
854
|
-
self._enl_axis_units = enl_axis_units
|
|
855
|
-
self._n_enl = len(enl_axis_names)
|
|
856
|
-
|
|
857
|
-
self._data_saver = DataEnlargeableSaver(h5saver)
|
|
858
|
-
self._nav_axis_saver = AxisSaverLoader(h5saver)
|
|
859
|
-
|
|
860
|
-
def add_data(self, where: Union[Node, str], data: DataToExport,
|
|
861
|
-
axis_values: List[Union[float, np.ndarray]] = None,
|
|
862
|
-
axis_value: Union[float, np.ndarray] = None,
|
|
863
|
-
settings_as_xml='', metadata=None,
|
|
864
|
-
):
|
|
865
|
-
"""
|
|
866
|
-
|
|
867
|
-
Parameters
|
|
868
|
-
----------
|
|
869
|
-
where: Union[Node, str]
|
|
870
|
-
the path of a given node or the node itself
|
|
871
|
-
data: DataToExport
|
|
872
|
-
The data to be saved into an enlargeable array
|
|
873
|
-
axis_values: iterable float or np.ndarray
|
|
874
|
-
The next value (or values) of the enlarged axis
|
|
875
|
-
axis_value: float or np.ndarray #deprecated in 4.2.0, use axis_values
|
|
876
|
-
The next value (or values) of the enlarged axis
|
|
877
|
-
settings_as_xml: str
|
|
878
|
-
The settings parameter as an XML string
|
|
879
|
-
metadata: dict
|
|
880
|
-
all extra metadata to be saved in the group node where data will be saved
|
|
881
|
-
"""
|
|
882
|
-
|
|
883
|
-
if axis_values is None and axis_value is not None:
|
|
884
|
-
axis_values = [axis_value]
|
|
885
|
-
|
|
886
|
-
super().add_data(where, data, settings_as_xml, metadata)
|
|
887
|
-
# a parent navigation group (same for all data nodes)
|
|
888
|
-
|
|
889
|
-
where = self._get_node(where)
|
|
890
|
-
nav_group = self._h5saver.get_set_group(where, SPECIAL_GROUP_NAMES['nav_axes'])
|
|
891
|
-
if self._nav_axis_saver.get_last_node_name(nav_group) is None:
|
|
892
|
-
for ind in range(self._n_enl):
|
|
893
|
-
axis = Axis(label=self._enl_axis_names[ind],
|
|
894
|
-
units=self._enl_axis_units[ind], data=np.array([0., 1.]),
|
|
895
|
-
index=0, spread_order=ind)
|
|
896
|
-
axis_array = self._nav_axis_saver.add_axis(nav_group, axis, enlargeable=True)
|
|
897
|
-
axis_array.attrs['size'] = 0
|
|
898
|
-
|
|
899
|
-
for ind in range(self._n_enl):
|
|
900
|
-
axis_array: EARRAY = self._nav_axis_saver.get_node_from_index(nav_group, ind)
|
|
901
|
-
axis_array.append(squeeze(np.array([axis_values[ind]])),
|
|
902
|
-
expand=False)
|
|
903
|
-
axis_array.attrs['size'] += 1
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
class DataToExportTimedSaver(DataToExportEnlargeableSaver):
|
|
907
|
-
"""Specialized DataToExportEnlargeableSaver to save data as a function of a time axis
|
|
908
|
-
|
|
909
|
-
Only one element ca be added at a time, the time axis value are enlarged using the data to be
|
|
910
|
-
added timestamp
|
|
911
|
-
|
|
912
|
-
Notes
|
|
913
|
-
-----
|
|
914
|
-
This object is made for continuous saving mode of DAQViewer and logging to h5file for DAQLogger
|
|
915
|
-
"""
|
|
916
|
-
def __init__(self, h5saver: H5Saver):
|
|
917
|
-
super().__init__(h5saver, enl_axis_names=('time',), enl_axis_units=('s',))
|
|
918
|
-
|
|
919
|
-
def add_data(self, where: Union[Node, str], data: DataToExport, settings_as_xml='',
|
|
920
|
-
metadata=None, **kwargs):
|
|
921
|
-
super().add_data(where, data, axis_values=[data.timestamp], settings_as_xml=settings_as_xml,
|
|
922
|
-
metadata=metadata)
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
class DataToExportExtendedSaver(DataToExportSaver):
|
|
926
|
-
"""Object to save DataToExport at given indexes within arrays including extended shape
|
|
927
|
-
|
|
928
|
-
Mostly used for data generated from the DAQScan
|
|
929
|
-
|
|
930
|
-
Parameters
|
|
931
|
-
----------
|
|
932
|
-
h5saver: H5Saver
|
|
933
|
-
extended_shape: Tuple[int]
|
|
934
|
-
the extra shape compared to the data the h5array will have
|
|
935
|
-
"""
|
|
936
|
-
|
|
937
|
-
def __init__(self, h5saver: H5Saver, extended_shape: Tuple[int]):
|
|
938
|
-
super().__init__(h5saver)
|
|
939
|
-
self._data_saver = DataExtendedSaver(h5saver, extended_shape)
|
|
940
|
-
self._nav_axis_saver = AxisSaverLoader(h5saver)
|
|
941
|
-
|
|
942
|
-
def add_nav_axes(self, where: Union[Node, str], axes: List[Axis]):
|
|
943
|
-
"""Used to add navigation axes related to the extended array
|
|
944
|
-
|
|
945
|
-
Notes
|
|
946
|
-
-----
|
|
947
|
-
For instance the scan axes in the DAQScan
|
|
948
|
-
"""
|
|
949
|
-
where = self._get_node(where)
|
|
950
|
-
nav_group = self._h5saver.get_set_group(where, SPECIAL_GROUP_NAMES['nav_axes'])
|
|
951
|
-
if self._nav_axis_saver.get_last_node_name(nav_group) is None:
|
|
952
|
-
for axis in axes:
|
|
953
|
-
self._nav_axis_saver.add_axis(nav_group, axis)
|
|
954
|
-
|
|
955
|
-
def add_data(self, where: Union[Node, str], data: DataToExport, indexes: Iterable[int],
|
|
956
|
-
distribution=DataDistribution['uniform'],
|
|
957
|
-
settings_as_xml='', metadata={}):
|
|
958
|
-
"""
|
|
959
|
-
|
|
960
|
-
Parameters
|
|
961
|
-
----------
|
|
962
|
-
where: Union[Node, str]
|
|
963
|
-
the path of a given node or the node itself
|
|
964
|
-
data: DataToExport
|
|
965
|
-
indexes: List[int]
|
|
966
|
-
indexes where to save data in the init h5array (should have the same length as
|
|
967
|
-
extended_shape and with values coherent with this shape
|
|
968
|
-
settings_as_xml: str
|
|
969
|
-
The settings parameter as an XML string
|
|
970
|
-
metadata: dict
|
|
971
|
-
all extra metadata to be saved in the group node where data will be saved
|
|
972
|
-
|
|
973
|
-
"""
|
|
974
|
-
dims = data.get_dim_presents()
|
|
975
|
-
for dim in dims:
|
|
976
|
-
dim_group = self._h5saver.get_set_group(where, dim)
|
|
977
|
-
for ind, dwa in enumerate(data.get_data_from_dim(dim)):
|
|
978
|
-
# dwa: DataWithAxes filtered by dim
|
|
979
|
-
dwa_group = self._h5saver.get_set_group(dim_group,
|
|
980
|
-
self.channel_formatter(ind), dwa.name)
|
|
981
|
-
self._data_saver.add_data(dwa_group, dwa, indexes=indexes,
|
|
982
|
-
distribution=distribution)
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
class DataLoader:
|
|
986
|
-
"""Specialized Object to load DataWithAxes object from a h5file
|
|
987
|
-
|
|
988
|
-
On the contrary to DataSaverLoader, does include navigation axes stored elsewhere in the h5file
|
|
989
|
-
(for instance if saved from the DAQ_Scan)
|
|
990
|
-
|
|
991
|
-
Parameters
|
|
992
|
-
----------
|
|
993
|
-
h5saver: H5Saver
|
|
994
|
-
"""
|
|
995
|
-
|
|
996
|
-
def __init__(self, h5saver: Union[H5Saver, Path]):
|
|
997
|
-
self._axis_loader: AxisSaverLoader = None
|
|
998
|
-
self._data_loader: DataSaverLoader = None
|
|
999
|
-
|
|
1000
|
-
if isinstance(h5saver, Path) or isinstance(h5saver, str):
|
|
1001
|
-
h5saver_tmp = H5Saver()
|
|
1002
|
-
h5saver_tmp.init_file(addhoc_file_path=Path(h5saver))
|
|
1003
|
-
h5saver = h5saver_tmp
|
|
1004
|
-
|
|
1005
|
-
self.h5saver = h5saver
|
|
1006
|
-
|
|
1007
|
-
@property
|
|
1008
|
-
def h5saver(self):
|
|
1009
|
-
return self._h5saver
|
|
1010
|
-
|
|
1011
|
-
def __enter__(self):
|
|
1012
|
-
return self
|
|
1013
|
-
|
|
1014
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
1015
|
-
self.close_file()
|
|
1016
|
-
|
|
1017
|
-
def close_file(self):
|
|
1018
|
-
self._h5saver.close_file()
|
|
1019
|
-
|
|
1020
|
-
def walk_nodes(self, where: Union[str, Node] = '/'):
|
|
1021
|
-
"""Return a Node generator iterating over the h5file content"""
|
|
1022
|
-
return self.h5saver.walk_nodes(where)
|
|
1023
|
-
|
|
1024
|
-
@h5saver.setter
|
|
1025
|
-
def h5saver(self, h5saver: H5Saver):
|
|
1026
|
-
self._h5saver = h5saver
|
|
1027
|
-
self._axis_loader = AxisSaverLoader(h5saver)
|
|
1028
|
-
self._data_loader = DataSaverLoader(h5saver)
|
|
1029
|
-
|
|
1030
|
-
def get_node(self, where: Union[Node, str], name: str = None) -> Node:
|
|
1031
|
-
""" Convenience method to get node"""
|
|
1032
|
-
return self.h5saver.get_node(where, name)
|
|
1033
|
-
|
|
1034
|
-
def get_nav_group(self, where: Union[Node, str]) -> Union[Node, None]:
|
|
1035
|
-
"""
|
|
1036
|
-
|
|
1037
|
-
Parameters
|
|
1038
|
-
----------
|
|
1039
|
-
where: Union[Node, str]
|
|
1040
|
-
the path of a given node or the node itself
|
|
1041
|
-
|
|
1042
|
-
Returns
|
|
1043
|
-
-------
|
|
1044
|
-
GROUP: returns the group named SPECIAL_GROUP_NAMES['nav_axes'] holding all NavAxis for
|
|
1045
|
-
those data
|
|
1046
|
-
|
|
1047
|
-
See Also
|
|
1048
|
-
--------
|
|
1049
|
-
SPECIAL_GROUP_NAMES
|
|
1050
|
-
"""
|
|
1051
|
-
node = self._h5saver.get_node(where)
|
|
1052
|
-
while node is not None: # means we reached the root level
|
|
1053
|
-
if isinstance(node, GROUP):
|
|
1054
|
-
if self._h5saver.is_node_in_group(node, SPECIAL_GROUP_NAMES['nav_axes']):
|
|
1055
|
-
return self._h5saver.get_node(node, SPECIAL_GROUP_NAMES['nav_axes'])
|
|
1056
|
-
node = node.parent_node
|
|
1057
|
-
|
|
1058
|
-
def load_data(self, where: Union[Node, str], with_bkg=False, load_all=False) -> DataWithAxes:
|
|
1059
|
-
"""Load data from a node (or channel node)
|
|
1060
|
-
|
|
1061
|
-
Loaded data contains also nav_axes if any and with optional background subtraction
|
|
1062
|
-
|
|
1063
|
-
Parameters
|
|
1064
|
-
----------
|
|
1065
|
-
where: Union[Node, str]
|
|
1066
|
-
the path of a given node or the node itself
|
|
1067
|
-
with_bkg: bool
|
|
1068
|
-
If True will attempt to substract a background data node before loading
|
|
1069
|
-
load_all: bool
|
|
1070
|
-
If True, will load all data hanging from the same parent node
|
|
1071
|
-
|
|
1072
|
-
Returns
|
|
1073
|
-
-------
|
|
1074
|
-
|
|
1075
|
-
"""
|
|
1076
|
-
node_data_type = DataType[self._h5saver.get_node(where).attrs['data_type']]
|
|
1077
|
-
self._data_loader.data_type = node_data_type
|
|
1078
|
-
data = self._data_loader.load_data(where, with_bkg=with_bkg, load_all=load_all)
|
|
1079
|
-
if 'axis' not in node_data_type.name:
|
|
1080
|
-
nav_group = self.get_nav_group(where)
|
|
1081
|
-
if nav_group is not None:
|
|
1082
|
-
nav_axes = self._axis_loader.get_axes(nav_group)
|
|
1083
|
-
axes = data.axes[:]
|
|
1084
|
-
axes.extend(nav_axes)
|
|
1085
|
-
data.axes = axes
|
|
1086
|
-
data.get_dim_from_data_axes()
|
|
1087
|
-
data.create_missing_axes()
|
|
1088
|
-
return data
|
|
1089
|
-
|
|
1090
|
-
def load_all(self, where: GROUP, data: DataToExport, with_bkg=False) -> DataToExport:
|
|
1091
|
-
|
|
1092
|
-
where = self._h5saver.get_node(where)
|
|
1093
|
-
children_dict = where.children()
|
|
1094
|
-
data_list = []
|
|
1095
|
-
for child in children_dict:
|
|
1096
|
-
if isinstance(children_dict[child], GROUP):
|
|
1097
|
-
self.load_all(children_dict[child], data, with_bkg=with_bkg)
|
|
1098
|
-
elif ('data_type' in children_dict[child].attrs and 'data' in
|
|
1099
|
-
children_dict[child].attrs['data_type']):
|
|
1100
|
-
|
|
1101
|
-
data_list.append(self.load_data(children_dict[child].path,
|
|
1102
|
-
with_bkg=with_bkg, load_all=True))
|
|
1103
|
-
break
|
|
1104
|
-
data_tmp = DataToExport(name=where.name, data=data_list)
|
|
1105
|
-
data.append(data_tmp)
|