pymodaq 3.6.13__py3-none-any.whl → 4.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 +13 -6
- pymodaq/control_modules/__init__.py +0 -7
- pymodaq/control_modules/daq_move.py +965 -2
- pymodaq/control_modules/daq_move_ui.py +319 -0
- pymodaq/control_modules/daq_viewer.py +1573 -3
- pymodaq/control_modules/daq_viewer_ui.py +393 -0
- pymodaq/control_modules/mocks.py +51 -0
- pymodaq/control_modules/move_utility_classes.py +709 -8
- pymodaq/control_modules/utils.py +256 -0
- pymodaq/control_modules/viewer_utility_classes.py +663 -6
- pymodaq/daq_utils.py +89 -0
- pymodaq/dashboard.py +91 -72
- pymodaq/examples/custom_app.py +12 -11
- pymodaq/examples/custom_viewer.py +10 -10
- pymodaq/examples/function_plotter.py +16 -13
- pymodaq/examples/nonlinearscanner.py +8 -6
- pymodaq/examples/parameter_ex.py +7 -7
- pymodaq/examples/preset_MockCamera.xml +1 -0
- pymodaq/extensions/__init__.py +16 -0
- pymodaq/extensions/console.py +76 -0
- pymodaq/{daq_logger.py → extensions/daq_logger.py} +115 -65
- pymodaq/extensions/daq_scan.py +1339 -0
- pymodaq/extensions/daq_scan_ui.py +240 -0
- pymodaq/extensions/h5browser.py +23 -0
- pymodaq/{pid → extensions/pid}/__init__.py +4 -2
- pymodaq/{pid → extensions/pid}/daq_move_PID.py +2 -2
- pymodaq/{pid → extensions/pid}/pid_controller.py +48 -36
- pymodaq/{pid → extensions/pid}/utils.py +52 -6
- pymodaq/extensions/utils.py +40 -0
- pymodaq/post_treatment/__init__.py +6 -0
- pymodaq/{daq_analysis → post_treatment/daq_analysis}/daq_analysis_main.py +17 -17
- pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_main.py +8 -14
- pymodaq/post_treatment/load_and_plot.py +219 -0
- pymodaq/post_treatment/process_to_scalar.py +263 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +1 -1
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +1 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +109784 -109173
- pymodaq/resources/QtDesigner_Ressources/icons.svg +142 -0
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/config_template.toml +32 -13
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/{daq_utils → utils}/Tuto innosetup/script_full_setup.iss +1 -1
- pymodaq/utils/__init__.py +0 -29
- pymodaq/utils/abstract/__init__.py +48 -0
- pymodaq/{daq_utils → utils}/abstract/logger.py +7 -3
- pymodaq/utils/array_manipulation.py +379 -8
- pymodaq/{daq_utils → utils}/calibration_camera.py +6 -6
- pymodaq/{daq_utils → utils}/chrono_timer.py +1 -1
- pymodaq/utils/config.py +448 -0
- pymodaq/utils/conftests.py +5 -0
- pymodaq/utils/daq_utils.py +828 -8
- pymodaq/utils/data.py +1873 -7
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger.py +86 -47
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger_models.py +31 -10
- pymodaq/{daq_utils → utils}/enums.py +12 -7
- pymodaq/utils/exceptions.py +37 -0
- pymodaq/utils/factory.py +82 -0
- pymodaq/{daq_utils → utils}/gui_utils/__init__.py +1 -1
- pymodaq/utils/gui_utils/custom_app.py +129 -0
- pymodaq/utils/gui_utils/file_io.py +66 -0
- pymodaq/{daq_utils → utils}/gui_utils/layout.py +2 -2
- pymodaq/{daq_utils → utils}/gui_utils/utils.py +13 -3
- pymodaq/{daq_utils → utils}/gui_utils/widgets/__init__.py +2 -2
- pymodaq/utils/gui_utils/widgets/label.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/lcd.py +12 -7
- pymodaq/{daq_utils → utils}/gui_utils/widgets/push.py +66 -2
- pymodaq/{daq_utils → utils}/gui_utils/widgets/qled.py +6 -4
- pymodaq/utils/gui_utils/widgets/spinbox.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/table.py +2 -2
- pymodaq/utils/h5modules/__init__.py +1 -0
- pymodaq/{daq_utils/h5backend.py → utils/h5modules/backends.py} +200 -112
- pymodaq/utils/h5modules/browsing.py +683 -0
- pymodaq/utils/h5modules/data_saving.py +839 -0
- pymodaq/utils/h5modules/h5logging.py +110 -0
- pymodaq/utils/h5modules/module_saving.py +350 -0
- pymodaq/utils/h5modules/saving.py +914 -0
- pymodaq/utils/h5modules/utils.py +85 -0
- pymodaq/utils/logger.py +64 -6
- pymodaq/utils/managers/action_manager.py +460 -0
- pymodaq/{daq_utils → utils}/managers/batchscan_manager.py +144 -112
- pymodaq/{daq_utils → utils}/managers/modules_manager.py +188 -114
- pymodaq/{daq_utils → utils}/managers/overshoot_manager.py +3 -3
- pymodaq/utils/managers/parameter_manager.py +110 -0
- pymodaq/{daq_utils → utils}/managers/preset_manager.py +17 -13
- pymodaq/{daq_utils → utils}/managers/preset_manager_utils.py +8 -7
- pymodaq/{daq_utils → utils}/managers/remote_manager.py +7 -6
- pymodaq/{daq_utils → utils}/managers/roi_manager.py +148 -57
- pymodaq/utils/math_utils.py +546 -10
- pymodaq/{daq_utils → utils}/messenger.py +5 -1
- pymodaq/utils/parameter/__init__.py +2 -15
- pymodaq/{daq_utils → utils}/parameter/ioxml.py +12 -6
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/__init__.py +1 -3
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/filedir.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/itemselect.py +3 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/led.py +1 -1
- pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +161 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/slide.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/table.py +1 -1
- pymodaq/utils/parameter/utils.py +206 -11
- pymodaq/utils/plotting/data_viewers/__init__.py +6 -0
- pymodaq/utils/plotting/data_viewers/viewer.py +393 -0
- pymodaq/utils/plotting/data_viewers/viewer0D.py +251 -0
- pymodaq/utils/plotting/data_viewers/viewer1D.py +574 -0
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer1Dbasic.py +8 -3
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D.py +292 -357
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D_basic.py +58 -75
- pymodaq/utils/plotting/data_viewers/viewerND.py +738 -0
- pymodaq/{daq_utils → utils}/plotting/gant_chart.py +2 -2
- pymodaq/{daq_utils → utils}/plotting/items/axis_scaled.py +4 -2
- pymodaq/{daq_utils → utils}/plotting/items/image.py +8 -6
- pymodaq/utils/plotting/navigator.py +355 -0
- pymodaq/utils/plotting/scan_selector.py +480 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +88 -0
- pymodaq/utils/plotting/utils/filter.py +538 -0
- pymodaq/utils/plotting/utils/lineout.py +224 -0
- pymodaq/{daq_utils → utils}/plotting/utils/plot_utils.py +196 -84
- pymodaq/{daq_utils → utils}/plotting/utils/signalND.py +21 -13
- pymodaq/utils/plotting/widgets.py +76 -0
- pymodaq/utils/scanner/__init__.py +10 -0
- pymodaq/utils/scanner/scan_factory.py +204 -0
- pymodaq/utils/scanner/scanner.py +271 -0
- pymodaq/utils/scanner/scanners/_1d_scanners.py +117 -0
- pymodaq/utils/scanner/scanners/_2d_scanners.py +293 -0
- pymodaq/utils/scanner/scanners/sequential.py +192 -0
- pymodaq/utils/scanner/scanners/tabular.py +294 -0
- pymodaq/utils/scanner/utils.py +83 -0
- pymodaq/utils/slicing.py +47 -0
- pymodaq/utils/svg/__init__.py +6 -0
- pymodaq/utils/svg/svg_renderer.py +20 -0
- pymodaq/utils/svg/svg_view.py +35 -0
- pymodaq/utils/svg/svg_viewer2D.py +51 -0
- pymodaq/{daq_utils → utils}/tcp_server_client.py +36 -37
- pymodaq/{daq_utils → utils}/tree_layout/tree_layout_main.py +50 -35
- pymodaq/utils/units.py +216 -0
- pymodaq-4.0.1.dist-info/METADATA +159 -0
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/WHEEL +1 -2
- pymodaq-4.0.1.dist-info/entry_points.txt +8 -0
- pymodaq/daq_move/daq_move_gui.py +0 -279
- pymodaq/daq_move/daq_move_gui.ui +0 -534
- pymodaq/daq_move/daq_move_main.py +0 -1042
- pymodaq/daq_move/process_from_QtDesigner_DAQ_Move_GUI.bat +0 -2
- pymodaq/daq_move/utility_classes.py +0 -686
- pymodaq/daq_scan.py +0 -2160
- pymodaq/daq_utils/array_manipulation.py +0 -386
- pymodaq/daq_utils/config.py +0 -273
- pymodaq/daq_utils/conftests.py +0 -7
- pymodaq/daq_utils/custom_parameter_tree.py +0 -9
- pymodaq/daq_utils/daq_enums.py +0 -133
- pymodaq/daq_utils/daq_utils.py +0 -1402
- pymodaq/daq_utils/exceptions.py +0 -71
- pymodaq/daq_utils/gui_utils/custom_app.py +0 -103
- pymodaq/daq_utils/gui_utils/file_io.py +0 -75
- pymodaq/daq_utils/gui_utils/widgets/spinbox.py +0 -9
- pymodaq/daq_utils/h5exporter_hyperspy.py +0 -115
- pymodaq/daq_utils/h5exporters.py +0 -242
- pymodaq/daq_utils/h5modules.py +0 -1559
- pymodaq/daq_utils/h5utils.py +0 -241
- pymodaq/daq_utils/managers/action_manager.py +0 -236
- pymodaq/daq_utils/managers/parameter_manager.py +0 -57
- pymodaq/daq_utils/math_utils.py +0 -705
- pymodaq/daq_utils/parameter/__init__.py +0 -1
- pymodaq/daq_utils/parameter/oldpymodaq_ptypes.py +0 -1626
- pymodaq/daq_utils/parameter/pymodaq_ptypes/pixmap.py +0 -85
- pymodaq/daq_utils/parameter/utils.py +0 -136
- pymodaq/daq_utils/plotting/data_viewers/__init__.py +0 -0
- pymodaq/daq_utils/plotting/data_viewers/process_from_QtDesigner_0DViewer_GUI.bat +0 -2
- pymodaq/daq_utils/plotting/data_viewers/viewer0D.py +0 -204
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.py +0 -89
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.ui +0 -131
- pymodaq/daq_utils/plotting/data_viewers/viewer1D.py +0 -781
- pymodaq/daq_utils/plotting/data_viewers/viewerND.py +0 -894
- pymodaq/daq_utils/plotting/data_viewers/viewerbase.py +0 -64
- pymodaq/daq_utils/plotting/items/__init__.py +0 -0
- pymodaq/daq_utils/plotting/navigator.py +0 -500
- pymodaq/daq_utils/plotting/scan_selector.py +0 -289
- pymodaq/daq_utils/plotting/utils/__init__.py +0 -0
- pymodaq/daq_utils/plotting/utils/filter.py +0 -236
- pymodaq/daq_utils/plotting/viewer0D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer0D/viewer0D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer1D/viewer1D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/viewer1Dbasic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_basic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewerND/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewerND/viewerND_main.py +0 -4
- pymodaq/daq_utils/scanner.py +0 -1289
- pymodaq/daq_utils/tree_layout/__init__.py +0 -0
- pymodaq/daq_viewer/__init__.py +0 -0
- pymodaq/daq_viewer/daq_gui_settings.py +0 -237
- pymodaq/daq_viewer/daq_gui_settings.ui +0 -441
- pymodaq/daq_viewer/daq_viewer_main.py +0 -2225
- pymodaq/daq_viewer/process_from_QtDesigner_DAQ_GUI_settings.bat +0 -2
- pymodaq/daq_viewer/utility_classes.py +0 -673
- pymodaq/examples/logger_image/__init__.py +0 -0
- pymodaq/examples/logger_image/logger_displayer.py +0 -121
- pymodaq/examples/logger_image/setup.svg +0 -3119
- pymodaq/examples/logger_image/setup_svg.py +0 -114
- pymodaq/h5browser.py +0 -39
- pymodaq/utils/scanner.py +0 -15
- pymodaq-3.6.13.dist-info/METADATA +0 -39
- pymodaq-3.6.13.dist-info/entry_points.txt +0 -8
- pymodaq-3.6.13.dist-info/top_level.txt +0 -1
- /pymodaq/{daq_analysis → post_treatment/daq_analysis}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.ui +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.odt +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.pdf +0 -0
- /pymodaq/{daq_move → utils/db}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils/db/db_logger}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/dock.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/list_picker.py +0 -0
- /pymodaq/{daq_utils/abstract → utils/managers}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/bool.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/date.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/list.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/numeric.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/tableview.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/text.py +0 -0
- /pymodaq/{daq_utils/db → utils/plotting}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/image_viewer.py +0 -0
- /pymodaq/{daq_utils/db/db_logger → utils/plotting/items}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/items/crosshair.py +0 -0
- /pymodaq/{daq_utils/managers → utils/plotting/utils}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/qvariant.py +0 -0
- /pymodaq/{daq_utils/plotting/viewer2D → utils/scanner/scanners}/__init__.py +0 -0
- /pymodaq/{daq_utils/plotting → utils/tree_layout}/__init__.py +0 -0
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import pymodaq.
|
|
1
|
+
import pymodaq.utils.gui_utils.file_io
|
|
2
2
|
from qtpy import QtGui, QtWidgets
|
|
3
3
|
from qtpy.QtCore import Qt, QObject, Signal, QByteArray
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
6
|
import pymodaq
|
|
7
|
-
import pymodaq.
|
|
8
|
-
from pymodaq.
|
|
9
|
-
from pymodaq.
|
|
7
|
+
import pymodaq.utils.parameter.ioxml
|
|
8
|
+
from pymodaq.utils.plotting.data_viewers.viewer1D import Viewer1D
|
|
9
|
+
from pymodaq.utils.plotting.data_viewers.viewer2D import Viewer2D
|
|
10
10
|
|
|
11
11
|
from collections import OrderedDict
|
|
12
12
|
import numpy as np
|
|
13
13
|
|
|
14
14
|
from pyqtgraph.parametertree import Parameter, ParameterTree
|
|
15
|
-
import pymodaq.
|
|
16
|
-
from pymodaq.
|
|
17
|
-
import pymodaq.
|
|
18
|
-
from pymodaq.
|
|
15
|
+
import pymodaq.utils.parameter.pymodaq_ptypes as pymodaq_ptypes
|
|
16
|
+
from pymodaq.utils.tree_layout.tree_layout_main import TreeLayout
|
|
17
|
+
import pymodaq.utils.daq_utils as utils
|
|
18
|
+
from pymodaq.utils import gui_utils as gutils
|
|
19
19
|
from easydict import EasyDict as edict
|
|
20
20
|
from pyqtgraph.dockarea import DockArea, Dock
|
|
21
21
|
import tables
|
|
@@ -90,7 +90,7 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
90
90
|
def set_GUI(self):
|
|
91
91
|
"""
|
|
92
92
|
Create the graphic interface of the h5 file analyser, including:
|
|
93
|
-
* *h5 file dock* : QtreeWidget (custom instance of
|
|
93
|
+
* *h5 file dock* : QtreeWidget (custom instance of TreeLayout) showing the contents of the h5 file
|
|
94
94
|
* *status bar* : the top_down information bar
|
|
95
95
|
* *tree_dock* : The QTree viewer
|
|
96
96
|
* *1D viewer dock* : the preview window of 1D data
|
|
@@ -103,7 +103,7 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
103
103
|
H_splitter = QtWidgets.QSplitter(Qt.Horizontal)
|
|
104
104
|
|
|
105
105
|
Form = QtWidgets.QWidget()
|
|
106
|
-
self.ui.h5file_tree =
|
|
106
|
+
self.ui.h5file_tree = TreeLayout(Form, col_counts=2, labels=["Node", 'Pixmap'])
|
|
107
107
|
self.ui.h5file_tree.ui.Tree.setMinimumWidth(250)
|
|
108
108
|
self.ui.h5file_tree.ui.Tree.itemClicked.connect(self.show_h5_attributes)
|
|
109
109
|
self.ui.h5file_tree.ui.Tree.itemDoubleClicked.connect(self.show_h5_data)
|
|
@@ -210,7 +210,7 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
210
210
|
do_load, close_h5, quit_fun
|
|
211
211
|
"""
|
|
212
212
|
file_menu = menubar.addMenu('File')
|
|
213
|
-
open_action = file_menu.addAction("Open
|
|
213
|
+
open_action = file_menu.addAction("Open DAQScan file")
|
|
214
214
|
open_action.triggered.connect(self.do_load)
|
|
215
215
|
close_action = file_menu.addAction("close h5 file")
|
|
216
216
|
close_action.triggered.connect(self.close_h5)
|
|
@@ -260,7 +260,7 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
260
260
|
open_h5_file, update_status, daq_utils.select_file
|
|
261
261
|
"""
|
|
262
262
|
try:
|
|
263
|
-
filename = pymodaq.
|
|
263
|
+
filename = pymodaq.utils.gui_utils.file_io.select_file(start_path=path, save=False, ext='h5')
|
|
264
264
|
if filename != "":
|
|
265
265
|
self.open_h5_file(filename)
|
|
266
266
|
except Exception as e:
|
|
@@ -344,7 +344,7 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
344
344
|
================= ====================== ====================================
|
|
345
345
|
**Parameters** **Type** **Description**
|
|
346
346
|
|
|
347
|
-
*item* tables
|
|
347
|
+
*item* tables GROUP instance contain the root node of the tree
|
|
348
348
|
|
|
349
349
|
*col* not used
|
|
350
350
|
================= ====================== ====================================
|
|
@@ -363,10 +363,10 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
363
363
|
for child in self.settings.children():
|
|
364
364
|
child.remove()
|
|
365
365
|
QtWidgets.QApplication.processEvents() # so that the tree associated with settings updates
|
|
366
|
-
params = pymodaq.
|
|
366
|
+
params = pymodaq.utils.parameter.ioxml.XML_string_to_parameter(attrs.settings.decode())
|
|
367
367
|
self.settings.addChildren(params)
|
|
368
368
|
if hasattr(attrs, 'scan_settings'):
|
|
369
|
-
params = pymodaq.
|
|
369
|
+
params = pymodaq.utils.parameter.ioxml.XML_string_to_parameter(attrs.scan_settings.decode())
|
|
370
370
|
self.settings.addChildren(params)
|
|
371
371
|
except Exception as e:
|
|
372
372
|
self.update_status(str(e), wait_time=self.wait_time)
|
|
@@ -382,7 +382,7 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
382
382
|
=============== ====================== ===================================
|
|
383
383
|
**Parameters** **Type** **Description**
|
|
384
384
|
|
|
385
|
-
*item* tables
|
|
385
|
+
*item* tables GROUP instance contain the root node of the tree
|
|
386
386
|
*col* not used
|
|
387
387
|
=============== ====================== ===================================
|
|
388
388
|
|
|
@@ -521,7 +521,7 @@ class DAQ_Analysis(QtWidgets.QWidget, QObject):
|
|
|
521
521
|
================ ======================= ==========================================
|
|
522
522
|
**Parameters** **Type** **Description**
|
|
523
523
|
|
|
524
|
-
*node* tables
|
|
524
|
+
*node* tables GROUP instance the root node of the local treated tree
|
|
525
525
|
================ ======================= ==========================================
|
|
526
526
|
|
|
527
527
|
Returns
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
from qtpy import
|
|
2
|
-
from qtpy.QtCore import Qt, QObject, Slot,
|
|
1
|
+
from qtpy import QtWidgets
|
|
2
|
+
from qtpy.QtCore import Qt, QObject, Slot, Signal
|
|
3
3
|
|
|
4
4
|
import sys
|
|
5
|
-
from pymodaq.daq_measurement.daq_measurement_GUI import Ui_Form
|
|
6
|
-
from pymodaq.
|
|
7
|
-
from pymodaq.
|
|
5
|
+
from pymodaq.post_treatment.daq_measurement.daq_measurement_GUI import Ui_Form
|
|
6
|
+
from pymodaq.utils import daq_utils as utils
|
|
7
|
+
from pymodaq.utils.plotting.utils.filter import FourierFilterer
|
|
8
8
|
from scipy.optimize import curve_fit
|
|
9
|
-
from scipy.signal import find_peaks
|
|
10
|
-
import pyqtgraph as pg
|
|
11
9
|
import numpy as np
|
|
12
|
-
from
|
|
10
|
+
from pymodaq.utils.enums import BaseEnum
|
|
13
11
|
|
|
14
12
|
|
|
15
|
-
class Measurement_type(
|
|
13
|
+
class Measurement_type(BaseEnum):
|
|
16
14
|
Cursor_Integration = 0
|
|
17
15
|
Max = 1
|
|
18
16
|
Min = 2
|
|
@@ -21,10 +19,6 @@ class Measurement_type(Enum):
|
|
|
21
19
|
Exponential_Decay_Fit = 5
|
|
22
20
|
Sinus = 6
|
|
23
21
|
|
|
24
|
-
@classmethod
|
|
25
|
-
def names(cls):
|
|
26
|
-
return [name for name, member in cls.__members__.items()]
|
|
27
|
-
|
|
28
22
|
@classmethod
|
|
29
23
|
def update_measurement_subtype(cls, mtype):
|
|
30
24
|
measurement_gaussian_subitems = ["amp", "dx", "x0", "offset"]
|
|
@@ -377,7 +371,7 @@ class DAQ_Measurement(Ui_Form, QObject):
|
|
|
377
371
|
if __name__ == '__main__':
|
|
378
372
|
app = QtWidgets.QApplication(sys.argv)
|
|
379
373
|
Form = QtWidgets.QWidget()
|
|
380
|
-
from pymodaq.
|
|
374
|
+
from pymodaq.utils.daq_utils import gauss1D
|
|
381
375
|
|
|
382
376
|
prog = DAQ_Measurement(Form)
|
|
383
377
|
xdata = np.linspace(0, 400, 401)
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created the 22/01/2023
|
|
4
|
+
|
|
5
|
+
@author: Sebastien Weber
|
|
6
|
+
"""
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
from typing import List, Union, Callable, Iterable
|
|
10
|
+
|
|
11
|
+
from qtpy import QtWidgets, QtCore
|
|
12
|
+
|
|
13
|
+
from pymodaq.utils.data import DataToExport, DataFromPlugins, DataDim, enum_checker
|
|
14
|
+
from pymodaq.utils.h5modules.data_saving import DataLoader
|
|
15
|
+
from pymodaq.utils.h5modules.saving import H5Saver
|
|
16
|
+
from pymodaq.utils.plotting.data_viewers.viewer import ViewerBase, ViewersEnum, ViewerDispatcher
|
|
17
|
+
from pymodaq.utils.gui_utils import Dock, DockArea
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class LoaderPlotter:
|
|
21
|
+
|
|
22
|
+
grouped_data1D_fullname = 'Grouped/Data1D'
|
|
23
|
+
|
|
24
|
+
def __init__(self, dockarea):
|
|
25
|
+
self.dockarea = dockarea
|
|
26
|
+
self.dispatcher = ViewerDispatcher(dockarea, title='ViewerDispatcher')
|
|
27
|
+
self._viewers: dict[str, ViewerBase] = None
|
|
28
|
+
self._viewer_docks: dict[str, ViewerBase] = None
|
|
29
|
+
self._viewer_types: List[ViewersEnum] = None
|
|
30
|
+
self._h5saver: H5Saver = None
|
|
31
|
+
self._data: DataToExport = None
|
|
32
|
+
self.dataloader: DataLoader = None
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def viewers(self) -> List[ViewerBase]:
|
|
36
|
+
return self.dispatcher.viewers
|
|
37
|
+
|
|
38
|
+
def connect_double_clicked(self, slot: Callable):
|
|
39
|
+
for viewer in self.viewers:
|
|
40
|
+
viewer.sig_double_clicked.connect(slot)
|
|
41
|
+
|
|
42
|
+
def disconnect(self, slot: Callable):
|
|
43
|
+
for viewer in self.viewers:
|
|
44
|
+
viewer.sig_double_clicked.disconnect(slot)
|
|
45
|
+
|
|
46
|
+
def clear_viewers(self):
|
|
47
|
+
self.dispatcher.remove_viewers(0)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def h5saver(self):
|
|
51
|
+
return self._h5saver
|
|
52
|
+
|
|
53
|
+
@h5saver.setter
|
|
54
|
+
def h5saver(self, h5saver: H5Saver):
|
|
55
|
+
self._h5saver = h5saver
|
|
56
|
+
self.dataloader = DataLoader(h5saver)
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def data(self) -> DataToExport:
|
|
60
|
+
return self._data
|
|
61
|
+
|
|
62
|
+
def load_data(self, filter_dims: List[Union[DataDim, str]] = None, filter_full_names: List[str] = None,
|
|
63
|
+
remove_navigation: bool = True, group_1D=False, average_axis=None, average_index: int = 0):
|
|
64
|
+
self._data = DataToExport('All')
|
|
65
|
+
self.dataloader.load_all('/', self._data)
|
|
66
|
+
|
|
67
|
+
if average_axis is not None:
|
|
68
|
+
for ind, data in enumerate(self._data):
|
|
69
|
+
current_data = data.inav[average_index, ...]
|
|
70
|
+
if average_index == 0:
|
|
71
|
+
data_to_append = data.inav[0:average_index + 1, ...]
|
|
72
|
+
else:
|
|
73
|
+
data_to_append = data.inav[0:average_index+1, ...].mean(axis=average_axis)
|
|
74
|
+
data_to_append.labels = [f'{label}_averaged' for label in data_to_append.labels]
|
|
75
|
+
current_data.append(data_to_append)
|
|
76
|
+
self._data[ind] = current_data
|
|
77
|
+
|
|
78
|
+
if remove_navigation:
|
|
79
|
+
for data in self._data:
|
|
80
|
+
data.nav_indexes = ()
|
|
81
|
+
data.transpose() # because usual ND data should be plotted here as 2D with the nav axes as the minor
|
|
82
|
+
# (horizontal)
|
|
83
|
+
|
|
84
|
+
if filter_dims is not None:
|
|
85
|
+
filter_dims[:] = [enum_checker(DataDim, dim) for dim in filter_dims]
|
|
86
|
+
self._data.data[:] = [data for data in self._data if data.dim in filter_dims]
|
|
87
|
+
|
|
88
|
+
if filter_full_names is not None:
|
|
89
|
+
self._data.data[:] = [data for data in self._data if data.get_full_name() in filter_full_names]
|
|
90
|
+
|
|
91
|
+
if group_1D:
|
|
92
|
+
data = self._data.get_data_from_dim('Data1D')
|
|
93
|
+
if len(data) > 0:
|
|
94
|
+
data1D_arrays = []
|
|
95
|
+
labels = []
|
|
96
|
+
for dwa in data:
|
|
97
|
+
data1D_arrays.extend(dwa.data)
|
|
98
|
+
labels.extend([f'{dwa.get_full_name()}/{label}' for label in dwa.labels])
|
|
99
|
+
self._data.remove(dwa)
|
|
100
|
+
|
|
101
|
+
data1D = DataFromPlugins(self.grouped_data1D_fullname.split('/')[1],
|
|
102
|
+
data=data1D_arrays, labels=labels,
|
|
103
|
+
origin=self.grouped_data1D_fullname.split('/')[0],
|
|
104
|
+
axes=dwa.axes)
|
|
105
|
+
self._data.append(data1D)
|
|
106
|
+
|
|
107
|
+
return self._data
|
|
108
|
+
|
|
109
|
+
def load_plot_data(self, **kwargs):
|
|
110
|
+
"""Load and plot all data from the current H5Saver
|
|
111
|
+
|
|
112
|
+
See Also
|
|
113
|
+
-----
|
|
114
|
+
load_data
|
|
115
|
+
"""
|
|
116
|
+
if 'target_at' in kwargs:
|
|
117
|
+
target_at = kwargs.pop('target_at')
|
|
118
|
+
self.load_data(**kwargs)
|
|
119
|
+
self.show_data(target_at=target_at)
|
|
120
|
+
|
|
121
|
+
def show_data(self, **kwargs):
|
|
122
|
+
"""Send data to their dedicated viewers
|
|
123
|
+
"""
|
|
124
|
+
#self._init_show_data(self._data)
|
|
125
|
+
self.set_data_to_viewers(self._data, **kwargs)
|
|
126
|
+
|
|
127
|
+
def _init_show_data(self, data: DataToExport):
|
|
128
|
+
"""Processing before showing data
|
|
129
|
+
"""
|
|
130
|
+
self._viewer_types = [ViewersEnum(data.dim.name) for data in data]
|
|
131
|
+
self.prepare_viewers(self._viewer_types)
|
|
132
|
+
|
|
133
|
+
def prepare_viewers(self, viewers_enum: List[ViewersEnum], viewers_name: List[str] = None):
|
|
134
|
+
if self._viewers is not None:
|
|
135
|
+
while len(self._viewers) > 0:
|
|
136
|
+
self._viewers.pop(list(self._viewers.keys())[0])
|
|
137
|
+
self._viewer_docks.pop(list(self._viewer_docks.keys())[0])
|
|
138
|
+
|
|
139
|
+
self._viewer_types = [enum_checker(ViewersEnum, viewer_enum) for viewer_enum in viewers_enum]
|
|
140
|
+
if viewers_name is None or len(viewers_enum) != len(viewers_name):
|
|
141
|
+
viewers_name = [f'DataPlot{ind:02d}' for ind in range(len(self._viewer_types))]
|
|
142
|
+
|
|
143
|
+
if self.dispatcher.viewer_types != self._viewer_types:
|
|
144
|
+
self.dispatcher.update_viewers(self._viewer_types)
|
|
145
|
+
|
|
146
|
+
self._viewers = dict(zip(viewers_name, self.dispatcher.viewers))
|
|
147
|
+
self._viewer_docks = dict(zip(viewers_name, self.dispatcher.viewer_docks))
|
|
148
|
+
|
|
149
|
+
def set_data_to_viewers(self, data: DataToExport, temp=False, target_at: Iterable[float] = None):
|
|
150
|
+
"""Process data dimensionality and send appropriate data to their data viewers
|
|
151
|
+
|
|
152
|
+
Parameters
|
|
153
|
+
----------
|
|
154
|
+
data: list of DataFromPlugins
|
|
155
|
+
temp: bool
|
|
156
|
+
if True notify the data viewers to display data as temporary (meaning not exporting processed data from roi)
|
|
157
|
+
target_at: Iterable[float]
|
|
158
|
+
if specified show and plot the roi_target of each viewer at the given position
|
|
159
|
+
See Also
|
|
160
|
+
--------
|
|
161
|
+
ViewerBase, Viewer0D, Viewer1D, Viewer2D
|
|
162
|
+
"""
|
|
163
|
+
for ind, _data in enumerate(data.data):
|
|
164
|
+
viewer = self._viewers[_data.get_full_name()]
|
|
165
|
+
self._viewer_docks[_data.get_full_name()].setTitle(_data.name)
|
|
166
|
+
|
|
167
|
+
# viewer = self.viewers[ind]
|
|
168
|
+
# self.dispatcher.viewer_docks[ind].setTitle(_data.name)
|
|
169
|
+
|
|
170
|
+
viewer.title = _data.name
|
|
171
|
+
if temp:
|
|
172
|
+
viewer.show_data_temp(_data)
|
|
173
|
+
else:
|
|
174
|
+
viewer.show_data(_data)
|
|
175
|
+
if target_at is not None:
|
|
176
|
+
viewer.show_roi_target(True)
|
|
177
|
+
if _data.dim == 'Data1D':
|
|
178
|
+
viewer.move_roi_target(target_at)
|
|
179
|
+
elif _data.dim == 'Data2D' and _data.distribution == 'uniform':
|
|
180
|
+
_target_at = target_at.copy()
|
|
181
|
+
|
|
182
|
+
size = [_data.get_axis_from_index(1)[0].scaling]
|
|
183
|
+
if len(_target_at) == 1: # means concatenation of 1D data
|
|
184
|
+
axis = _data.get_axis_from_index(0)[0]
|
|
185
|
+
size.append(axis.scaling * axis.size)
|
|
186
|
+
_target_at = list(_target_at) + [axis.offset]
|
|
187
|
+
else:
|
|
188
|
+
size.append(_data.get_axis_from_index(0)[0].scaling)
|
|
189
|
+
viewer.move_roi_target(_target_at, size)
|
|
190
|
+
|
|
191
|
+
def main(init_qt=True):
|
|
192
|
+
if init_qt: # used for the test suite
|
|
193
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
194
|
+
|
|
195
|
+
path = r'C:\Users\weber\Downloads\temp_data.h5'
|
|
196
|
+
|
|
197
|
+
h5saver = H5Saver()
|
|
198
|
+
h5saver.open_file(path)
|
|
199
|
+
|
|
200
|
+
win = QtWidgets.QMainWindow()
|
|
201
|
+
area = DockArea()
|
|
202
|
+
win.setCentralWidget(area)
|
|
203
|
+
win.resize(1000, 500)
|
|
204
|
+
win.setWindowTitle('PyMoDAQ Viewer')
|
|
205
|
+
win.show()
|
|
206
|
+
|
|
207
|
+
loader = LoaderPlotter(area)
|
|
208
|
+
loader.h5saver = h5saver
|
|
209
|
+
data = loader.load_data(filter_dims=['Data2D', 'Data1D'], group_1D=True)
|
|
210
|
+
loader._init_show_data(data)
|
|
211
|
+
loader.show_data()
|
|
212
|
+
|
|
213
|
+
if init_qt:
|
|
214
|
+
sys.exit(app.exec_())
|
|
215
|
+
return loader, win
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
if __name__ == '__main__':
|
|
219
|
+
main()
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created the 04/11/2022
|
|
4
|
+
|
|
5
|
+
@author: Sebastien Weber
|
|
6
|
+
"""
|
|
7
|
+
import numpy as np
|
|
8
|
+
from numbers import Number
|
|
9
|
+
from typing import List, Tuple
|
|
10
|
+
from abc import ABCMeta, abstractmethod, abstractproperty
|
|
11
|
+
|
|
12
|
+
from pymodaq.utils.factory import ObjectFactory
|
|
13
|
+
from pymodaq.utils import math_utils as mutils
|
|
14
|
+
from pymodaq.utils.data import DataWithAxes, Axis, DataRaw, DataBase, DataDim, DataCalculated
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
config_processors = {
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DataProcessorBase(metaclass=ABCMeta):
|
|
22
|
+
"""Apply processing functions to signal data. This function should return a scalar.
|
|
23
|
+
|
|
24
|
+
Attributes
|
|
25
|
+
----------
|
|
26
|
+
apply_to: DataDim
|
|
27
|
+
Specify on which type of data dimensionality this processor can be applied to, if only 1D:
|
|
28
|
+
apply_to = DataDim['Data1D']
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
apply_to: DataDim = abstractproperty
|
|
33
|
+
|
|
34
|
+
def process(self, data: DataWithAxes) -> DataWithAxes:
|
|
35
|
+
return self.operate(data)
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
def operate(self, sub_data: DataWithAxes):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def flatten_signal_dim(sub_data: DataWithAxes) -> Tuple[Tuple, np.ndarray]:
|
|
43
|
+
"""flattens data's ndarrays along the signal dimensions"""
|
|
44
|
+
data_arrays = []
|
|
45
|
+
new_shape = [sub_data.shape[ind] for ind in sub_data.nav_indexes]
|
|
46
|
+
new_shape.append(np.prod([sub_data.shape[ind] for ind in sub_data.sig_indexes]))
|
|
47
|
+
|
|
48
|
+
# for each data in subdata, apply the function, here argmax, along the flattened dimension. Then unravel the
|
|
49
|
+
# possible multiple indexes (1 for 1D, 2 for 2D)
|
|
50
|
+
for ind, data in enumerate(sub_data):
|
|
51
|
+
data_arrays.append(data.reshape(new_shape))
|
|
52
|
+
return new_shape, data_arrays
|
|
53
|
+
|
|
54
|
+
def __call__(self, **kwargs):
|
|
55
|
+
return self(**kwargs)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class DataProcessorFactory(ObjectFactory):
|
|
59
|
+
def get(self, processor_name, **kwargs) -> DataProcessorBase:
|
|
60
|
+
return self.create(processor_name, **kwargs)
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def functions(self):
|
|
64
|
+
"""Get the list of processor functions"""
|
|
65
|
+
return self.keys_function(do_sort=False)
|
|
66
|
+
|
|
67
|
+
def functions_filtered(self, dim: DataDim):
|
|
68
|
+
"""Get the list of processor functions that could be applied to data having a given dimensionality"""
|
|
69
|
+
return [key for key in self.functions if self.get(key).apply_to >= dim]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@DataProcessorFactory.register('mean')
|
|
73
|
+
class MeanProcessor(DataProcessorBase):
|
|
74
|
+
apply_to = DataDim['DataND']
|
|
75
|
+
|
|
76
|
+
def operate(self, sub_data: DataWithAxes):
|
|
77
|
+
data_arrays = [np.atleast_1d(np.mean(data, axis=sub_data.sig_indexes)) for data in sub_data]
|
|
78
|
+
return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@DataProcessorFactory.register('std')
|
|
82
|
+
class StdProcessor(DataProcessorBase):
|
|
83
|
+
apply_to = DataDim['DataND']
|
|
84
|
+
|
|
85
|
+
def operate(self, sub_data: DataWithAxes):
|
|
86
|
+
data_arrays = [np.atleast_1d(np.std(data, axis=sub_data.sig_indexes)) for data in sub_data]
|
|
87
|
+
return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@DataProcessorFactory.register('sum')
|
|
91
|
+
class SumProcessor(DataProcessorBase):
|
|
92
|
+
apply_to = DataDim['DataND']
|
|
93
|
+
|
|
94
|
+
def operate(self, sub_data: DataWithAxes):
|
|
95
|
+
data_arrays = [np.atleast_1d(np.sum(data, axis=sub_data.sig_indexes)) for data in sub_data]
|
|
96
|
+
return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@DataProcessorFactory.register('max')
|
|
100
|
+
class MaxProcessor(DataProcessorBase):
|
|
101
|
+
apply_to = DataDim['DataND']
|
|
102
|
+
|
|
103
|
+
def operate(self, sub_data: DataWithAxes):
|
|
104
|
+
data_arrays = [np.atleast_1d(np.max(data, axis=sub_data.sig_indexes)) for data in sub_data]
|
|
105
|
+
return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@DataProcessorFactory.register('min')
|
|
109
|
+
class MinProcessor(DataProcessorBase):
|
|
110
|
+
apply_to = DataDim['DataND']
|
|
111
|
+
|
|
112
|
+
def operate(self, sub_data: DataWithAxes):
|
|
113
|
+
data_arrays = [np.atleast_1d(np.min(data, axis=sub_data.sig_indexes)) for data in sub_data]
|
|
114
|
+
return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@DataProcessorFactory.register('argmax')
|
|
118
|
+
class ArgMaxProcessor(DataProcessorBase):
|
|
119
|
+
apply_to = DataDim['DataND']
|
|
120
|
+
|
|
121
|
+
def operate(self, sub_data: DataWithAxes):
|
|
122
|
+
"""Extract info from sub-DataWithAxes
|
|
123
|
+
|
|
124
|
+
Retrieve the signal axis values of the maximum position of the data
|
|
125
|
+
|
|
126
|
+
Notes
|
|
127
|
+
-----
|
|
128
|
+
For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
|
|
129
|
+
(compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
|
|
130
|
+
the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
|
|
131
|
+
a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
|
|
132
|
+
dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
|
|
133
|
+
"""
|
|
134
|
+
new_data_arrays = []
|
|
135
|
+
new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
|
|
136
|
+
|
|
137
|
+
for dat in flattened_arrays:
|
|
138
|
+
indexes = np.unravel_index(np.nanargmax(dat, len(new_shape)-1), sub_data.shape)[len(sub_data.nav_indexes):]
|
|
139
|
+
# from the unraveled index, retrieve the corresponding axis value
|
|
140
|
+
for ind in range(len(indexes)):
|
|
141
|
+
axis_data = sub_data.get_axis_from_index(sub_data.sig_indexes[ind])[0].get_data()
|
|
142
|
+
new_data_arrays.append(np.atleast_1d(axis_data[indexes[ind]]))
|
|
143
|
+
return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
|
|
144
|
+
axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes],
|
|
145
|
+
distribution=sub_data.distribution)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@DataProcessorFactory.register('argmin')
|
|
149
|
+
class ArgMinProcessor(DataProcessorBase):
|
|
150
|
+
apply_to = DataDim['DataND']
|
|
151
|
+
|
|
152
|
+
def operate(self, sub_data: DataWithAxes):
|
|
153
|
+
"""Extract info from sub-DataWithAxes
|
|
154
|
+
|
|
155
|
+
Retrieve the signal axis values of the minimum position of the data
|
|
156
|
+
|
|
157
|
+
Notes
|
|
158
|
+
-----
|
|
159
|
+
For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
|
|
160
|
+
(compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
|
|
161
|
+
the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
|
|
162
|
+
a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
|
|
163
|
+
dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
|
|
164
|
+
"""
|
|
165
|
+
new_data_arrays = []
|
|
166
|
+
new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
|
|
167
|
+
|
|
168
|
+
for dat in flattened_arrays:
|
|
169
|
+
indexes = np.unravel_index(np.nanargmin(dat, len(new_shape)-1), sub_data.shape)[len(sub_data.nav_indexes):]
|
|
170
|
+
# from the unraveled index, retrieve the corresponding axis value
|
|
171
|
+
for ind in range(len(indexes)):
|
|
172
|
+
axis_data = sub_data.get_axis_from_index(sub_data.sig_indexes[ind])[0].get_data()
|
|
173
|
+
new_data_arrays.append(np.atleast_1d(axis_data[indexes[ind]]))
|
|
174
|
+
return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
|
|
175
|
+
axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes],
|
|
176
|
+
distribution=sub_data.distribution)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@DataProcessorFactory.register('argmean')
|
|
180
|
+
class ArgMeanProcessor(DataProcessorBase):
|
|
181
|
+
apply_to = DataDim['Data1D']
|
|
182
|
+
|
|
183
|
+
def operate(self, sub_data: DataWithAxes):
|
|
184
|
+
"""Extract info from sub-DataWithAxes
|
|
185
|
+
|
|
186
|
+
Retrieve the signal mean axis values
|
|
187
|
+
|
|
188
|
+
Notes
|
|
189
|
+
-----
|
|
190
|
+
For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
|
|
191
|
+
(compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
|
|
192
|
+
the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
|
|
193
|
+
a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
|
|
194
|
+
dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
|
|
195
|
+
"""
|
|
196
|
+
new_data_arrays = []
|
|
197
|
+
new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
|
|
198
|
+
values = sub_data.get_axis_from_index(sub_data.sig_indexes[0])[0].get_data()
|
|
199
|
+
for dat in flattened_arrays:
|
|
200
|
+
weights = dat
|
|
201
|
+
new_data_arrays.append(np.atleast_1d(np.average(values, axis=len(new_shape) - 1, weights=weights)))
|
|
202
|
+
return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
|
|
203
|
+
axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes])
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@DataProcessorFactory.register('argstd')
|
|
207
|
+
class ArgStdProcessor(DataProcessorBase):
|
|
208
|
+
apply_to = DataDim['Data1D']
|
|
209
|
+
|
|
210
|
+
def operate(self, sub_data: DataWithAxes):
|
|
211
|
+
"""Extract info from sub-DataWithAxes
|
|
212
|
+
|
|
213
|
+
Retrieve the signal mean axis values
|
|
214
|
+
|
|
215
|
+
Notes
|
|
216
|
+
-----
|
|
217
|
+
For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
|
|
218
|
+
(compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
|
|
219
|
+
the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
|
|
220
|
+
a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
|
|
221
|
+
dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
|
|
222
|
+
"""
|
|
223
|
+
new_data_arrays = []
|
|
224
|
+
new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
|
|
225
|
+
values = sub_data.get_axis_from_index(sub_data.sig_indexes[0])[0].get_data()
|
|
226
|
+
for dat in flattened_arrays:
|
|
227
|
+
weights = dat
|
|
228
|
+
w_avg = np.atleast_1d(np.average(values, axis=len(new_shape) - 1, weights=weights))
|
|
229
|
+
new_data_arrays.append(np.atleast_1d(np.sqrt(
|
|
230
|
+
np.sum(weights * (values - w_avg) ** 2, axis=len(new_shape) - 1) /
|
|
231
|
+
np.sum(weights, axis=len(new_shape) - 1))))
|
|
232
|
+
return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
|
|
233
|
+
axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes])
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
if __name__ == '__main__':
|
|
237
|
+
import copy
|
|
238
|
+
processors = DataProcessorFactory()
|
|
239
|
+
print('Builders:\n'
|
|
240
|
+
f'{processors.builders}')
|
|
241
|
+
|
|
242
|
+
print('Math functions:\n'
|
|
243
|
+
f'{processors.functions}')
|
|
244
|
+
|
|
245
|
+
# test 2D signals
|
|
246
|
+
Nsigx = 200
|
|
247
|
+
Nsigy = 100
|
|
248
|
+
Nnav = 10
|
|
249
|
+
x = np.linspace(-Nsigx / 2, Nsigx / 2 - 1, Nsigx)
|
|
250
|
+
y = np.linspace(-Nsigy / 2, Nsigy / 2 - 1, Nsigy)
|
|
251
|
+
|
|
252
|
+
dat = np.zeros((Nnav, Nsigy, Nsigx))
|
|
253
|
+
for ind in range(Nnav):
|
|
254
|
+
dat[ind] = ind * mutils.gauss2D(x, 10 * (ind - Nnav / 2), 25 / np.sqrt(2),
|
|
255
|
+
y, 2 * (ind - Nnav / 2), 10 / np.sqrt(2))
|
|
256
|
+
|
|
257
|
+
data = DataRaw('mydata', data=[dat], nav_indexes=(0,),
|
|
258
|
+
axes=[Axis('nav', data=np.linspace(0, Nnav-1, Nnav), index=0),
|
|
259
|
+
Axis('sigy', data=y, index=1),
|
|
260
|
+
Axis('sigx', data=x, index=2)])
|
|
261
|
+
new_data = processors.get('sum', **config_processors).operate(data.isig[25:75, 75:125])
|
|
262
|
+
print(new_data)
|
|
263
|
+
print(new_data.data)
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
cd "C:\Users\Weber\Labo\Programmes Python\PyMoDAQ_Git\pymodaq\src\pymodaq\resources\QtDesigner_Ressources"
|
|
2
|
-
C:\Miniconda3\envs\
|
|
2
|
+
C:\Miniconda3\envs\qt5tools\Scripts\pyrcc5 QtDesigner_ressources.qrc > QtDesigner_ressources_rc.py
|