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
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created the 03/11/2022
|
|
4
|
+
|
|
5
|
+
@author: Sebastien Weber
|
|
6
|
+
"""
|
|
7
|
+
from collections import OrderedDict
|
|
8
|
+
from pyqtgraph import PlotCurveItem
|
|
9
|
+
from qtpy.QtCore import QObject, Signal, Slot
|
|
10
|
+
from pymodaq.utils.plotting.utils.plot_utils import Data0DWithHistory
|
|
11
|
+
from pymodaq.utils.managers.roi_manager import ROIManager
|
|
12
|
+
from pymodaq.utils.plotting.items.crosshair import Crosshair
|
|
13
|
+
from pymodaq.utils.logger import set_logger, get_module_name
|
|
14
|
+
import pymodaq.utils.daq_utils as utils
|
|
15
|
+
from pymodaq.utils.logger import set_logger, get_module_name
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
logger = set_logger(get_module_name(__file__))
|
|
19
|
+
IMAGE_TYPES = ['red', 'green', 'blue']
|
|
20
|
+
COLOR_LIST = utils.plot_colors
|
|
21
|
+
COLORS_DICT = dict(red=(255, 0, 0), green=(0, 255, 0), blue=(0, 0, 255), spread=(128, 128, 128))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def curve_item_factory(pen='red'):
|
|
25
|
+
"""
|
|
26
|
+
Create a PlotCurveItem with the given pen
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
pen: any type of arguments accepted by pyqtgraph.function.mkColor or one of the COLORS_DICT key
|
|
30
|
+
|
|
31
|
+
Returns
|
|
32
|
+
-------
|
|
33
|
+
PlotCurveItem
|
|
34
|
+
"""
|
|
35
|
+
if isinstance(pen, str):
|
|
36
|
+
if pen in COLORS_DICT:
|
|
37
|
+
pen = COLORS_DICT[pen]
|
|
38
|
+
return PlotCurveItem(pen=pen)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class LineoutPlotter(QObject):
|
|
42
|
+
"""Base class to manage and display data filtered out into lineouts (1D, 0D)
|
|
43
|
+
|
|
44
|
+
Should be inherited and subclass some methods as appropriate
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
graph_widgets: OrderedDict
|
|
49
|
+
Includes plotwidgets to display data
|
|
50
|
+
roi_manager:
|
|
51
|
+
The ROIManager to create ROIs and manage their properties
|
|
52
|
+
crosshair:
|
|
53
|
+
The Crosshair object
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
roi_changed = Signal(dict)
|
|
57
|
+
crosshair_lineout_plotted = Signal(dict)
|
|
58
|
+
roi_lineout_plotted = Signal(dict)
|
|
59
|
+
|
|
60
|
+
lineout_widgets = ['int'] # should be reimplemented see viewer2D
|
|
61
|
+
|
|
62
|
+
def __init__(self, graph_widgets: OrderedDict, roi_manager: ROIManager, crosshair: Crosshair):
|
|
63
|
+
super().__init__()
|
|
64
|
+
|
|
65
|
+
self._roi_manager = roi_manager
|
|
66
|
+
self._crosshair = crosshair
|
|
67
|
+
|
|
68
|
+
self._lineout_widgets = graph_widgets['lineouts']
|
|
69
|
+
|
|
70
|
+
self.integrated_data = Data0DWithHistory()
|
|
71
|
+
|
|
72
|
+
self._roi_curves = OrderedDict()
|
|
73
|
+
self._crosshair_curves = OrderedDict()
|
|
74
|
+
self._data_integrated = []
|
|
75
|
+
|
|
76
|
+
self.setup_crosshair()
|
|
77
|
+
|
|
78
|
+
self._roi_manager.new_ROI_signal.connect(self.add_ROI)
|
|
79
|
+
self._roi_manager.remove_ROI_signal.connect(self.remove_ROI)
|
|
80
|
+
self._roi_manager.roi_value_changed.connect(self.update_roi)
|
|
81
|
+
|
|
82
|
+
def plot_roi_lineouts(self, roi_dicts):
|
|
83
|
+
self.integrated_data.add_datas({roi_key: roi_dicts[roi_key].int_data for roi_key in roi_dicts})
|
|
84
|
+
for roi_key, lineout_data in roi_dicts.items():
|
|
85
|
+
if roi_key in self._roi_curves:
|
|
86
|
+
self._roi_curves[roi_key]['int'].setData(self.integrated_data.xaxis,
|
|
87
|
+
self.integrated_data.datas[roi_key])
|
|
88
|
+
self.plot_other_lineouts(roi_dicts)
|
|
89
|
+
|
|
90
|
+
logger.debug('roi lineouts plotted')
|
|
91
|
+
self.roi_lineout_plotted.emit(roi_dicts)
|
|
92
|
+
|
|
93
|
+
def plot_other_lineouts(self, roi_dicts):
|
|
94
|
+
raise NotImplementedError
|
|
95
|
+
|
|
96
|
+
def plot_crosshair_lineouts(self, crosshair_dict):
|
|
97
|
+
self.plot_other_crosshair_lineouts(crosshair_dict)
|
|
98
|
+
|
|
99
|
+
logger.debug('crosshair lineouts plotted')
|
|
100
|
+
self.crosshair_lineout_plotted.emit(crosshair_dict)
|
|
101
|
+
|
|
102
|
+
def plot_other_crosshair_lineouts(self, crosshair_dict):
|
|
103
|
+
raise NotImplementedError
|
|
104
|
+
|
|
105
|
+
def get_lineout_widget(self, name):
|
|
106
|
+
if name not in self.lineout_widgets:
|
|
107
|
+
raise KeyError(f'The lineout_widget reference should be within {self.lineout_widgets} not {name}')
|
|
108
|
+
return self._lineout_widgets[name]
|
|
109
|
+
|
|
110
|
+
@Slot(str, tuple)
|
|
111
|
+
def update_roi(self, roi_key, param_changed):
|
|
112
|
+
param, param_value = param_changed
|
|
113
|
+
|
|
114
|
+
if param.name() == 'Color':
|
|
115
|
+
for curve in self._roi_curves[roi_key].values():
|
|
116
|
+
curve.setPen(param_value)
|
|
117
|
+
|
|
118
|
+
self.roi_changed.emit(self._roi_manager.ROIs)
|
|
119
|
+
|
|
120
|
+
@Slot(str)
|
|
121
|
+
def remove_ROI(self, roi_name):
|
|
122
|
+
index = int(roi_name.split('_')[1])
|
|
123
|
+
self.remove_roi_lineout_items(index)
|
|
124
|
+
self.roi_changed.emit(self._roi_manager.ROIs)
|
|
125
|
+
|
|
126
|
+
@Slot(int, str)
|
|
127
|
+
def add_ROI(self, newindex, roi_type):
|
|
128
|
+
item = self._roi_manager.get_roi_from_index(newindex)
|
|
129
|
+
item.sigRegionChangeFinished.connect(lambda: self.roi_changed.emit(self._roi_manager.ROIs))
|
|
130
|
+
item_param = self._roi_manager.settings.child('ROIs', 'ROI_{:02d}'.format(newindex))
|
|
131
|
+
color = item_param.child('Color').value()
|
|
132
|
+
|
|
133
|
+
self.add_roi_lineout_items(newindex, color)
|
|
134
|
+
self.roi_changed.emit(self._roi_manager.ROIs)
|
|
135
|
+
|
|
136
|
+
def add_roi_lineout_items(self, index, pen):
|
|
137
|
+
"""
|
|
138
|
+
Add specifics lineouts generated from ROIs
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
index: (int) index of the ROI generating these lineouts
|
|
142
|
+
pen: (str, tuple) any argument able to generate a QPen, see pyqtgraph.functions.mkPen
|
|
143
|
+
"""
|
|
144
|
+
self._roi_curves[f'ROI_{index:02d}'] = \
|
|
145
|
+
{curv_key: curve_item_factory(pen) for curv_key in self.lineout_widgets}
|
|
146
|
+
self.add_lineout_items(*self._roi_curves[f'ROI_{index:02d}'].values())
|
|
147
|
+
|
|
148
|
+
def remove_roi_lineout_items(self, index):
|
|
149
|
+
"""
|
|
150
|
+
Remove specifics lineouts generated from ROI referenced by a unique integer
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
index: (int) index of the ROI generating these lineouts
|
|
154
|
+
"""
|
|
155
|
+
items = self._roi_curves.pop(f'ROI_{index:02d}')
|
|
156
|
+
self.remove_lineout_items(*items.values())
|
|
157
|
+
|
|
158
|
+
def add_lineout_items(self, *curve_items):
|
|
159
|
+
"""
|
|
160
|
+
Add Curve items sequentially to lineouts widgets: (hor, ver and int)
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
curve_items: (PlotCurveItem) at most 3 of them
|
|
164
|
+
"""
|
|
165
|
+
for ind, curve_item in enumerate(curve_items):
|
|
166
|
+
self.get_lineout_widget(self.lineout_widgets[ind]).addItem(curve_item)
|
|
167
|
+
|
|
168
|
+
def remove_lineout_items(self, *curve_items):
|
|
169
|
+
"""
|
|
170
|
+
Remove Curve items sequentially to lineouts widgets: (hor, ver and int)
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
curve_items: (PlotCurveItem) at most 3 of them
|
|
174
|
+
"""
|
|
175
|
+
|
|
176
|
+
for ind, curve_item in enumerate(curve_items):
|
|
177
|
+
self.get_lineout_widget(self.lineout_widgets[ind]).removeItem(curve_item)
|
|
178
|
+
|
|
179
|
+
@Slot(bool)
|
|
180
|
+
def roi_clicked(self, isroichecked=True):
|
|
181
|
+
self._roi_manager.roiwidget.setVisible(isroichecked)
|
|
182
|
+
|
|
183
|
+
for k, roi in self._roi_manager.ROIs.items():
|
|
184
|
+
roi.setVisible(isroichecked)
|
|
185
|
+
for item in self.get_roi_curves_triplet()[k].values():
|
|
186
|
+
item.setVisible(isroichecked)
|
|
187
|
+
|
|
188
|
+
@Slot(bool)
|
|
189
|
+
def crosshair_clicked(self, iscrosshairchecked=True):
|
|
190
|
+
for image_key in IMAGE_TYPES:
|
|
191
|
+
self.show_crosshair_curves(image_key, iscrosshairchecked)
|
|
192
|
+
|
|
193
|
+
def get_roi_curves_triplet(self):
|
|
194
|
+
"""
|
|
195
|
+
Get the dictionary (one key by ROI) containing dicts with ROI PlotCurveItem
|
|
196
|
+
|
|
197
|
+
Example:
|
|
198
|
+
--------
|
|
199
|
+
>>> roi_dict_triplet = self.get_roi_cruves_triplet()
|
|
200
|
+
>>> hor_curve = roi_dict_triplet['ROI_00']['hor'] # where 'hor' is an entry of self.lineout_widgets
|
|
201
|
+
"""
|
|
202
|
+
return self._roi_curves
|
|
203
|
+
|
|
204
|
+
def get_crosshair_curves_triplet(self):
|
|
205
|
+
"""
|
|
206
|
+
Get the dictionary (one key by ImageItem, see IMAGE_TYPES) containing dicts with PlotCurveItem
|
|
207
|
+
|
|
208
|
+
Example:
|
|
209
|
+
--------
|
|
210
|
+
>>> crosshair_dict_triplet = self.get_crosshair_curves_triplet()
|
|
211
|
+
>>> hor_curve = crosshair_dict_triplet['blue']['hor'] # where 'hor' is an entry of self.lineout_widgets
|
|
212
|
+
"""
|
|
213
|
+
return self._crosshair_curves
|
|
214
|
+
|
|
215
|
+
def get_crosshair_curve_triplet(self, curve_name):
|
|
216
|
+
return self._crosshair_curves[curve_name]
|
|
217
|
+
|
|
218
|
+
def setup_crosshair(self):
|
|
219
|
+
"""to reimplement if needed"""
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
def show_crosshair_curves(self, curve_key, show=True):
|
|
223
|
+
"""to reimplement if needed"""
|
|
224
|
+
pass
|
|
@@ -1,14 +1,160 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
|
|
3
|
+
import copy
|
|
4
|
+
from numbers import Real, Number
|
|
5
|
+
from typing import List, Union
|
|
6
|
+
from typing import Iterable as IterableType
|
|
7
|
+
|
|
8
|
+
from easydict import EasyDict as edict
|
|
1
9
|
from multipledispatch import dispatch
|
|
2
|
-
from pymodaq.daq_utils.plotting.items.axis_scaled import AxisItem_Scaled
|
|
3
|
-
from qtpy import QtGui, QtCore
|
|
4
|
-
import pyqtgraph as pg
|
|
5
10
|
import numpy as np
|
|
11
|
+
import pyqtgraph as pg
|
|
12
|
+
from qtpy import QtGui, QtCore, QtWidgets
|
|
6
13
|
from scipy.spatial import Delaunay as Triangulation
|
|
7
|
-
import copy
|
|
8
|
-
from easydict import EasyDict as edict
|
|
9
14
|
|
|
10
|
-
from pymodaq.
|
|
11
|
-
from pymodaq.
|
|
15
|
+
from pymodaq.utils import data as data_mod
|
|
16
|
+
from pymodaq.utils.plotting.items.axis_scaled import AxisItem_Scaled
|
|
17
|
+
from pymodaq.utils.plotting.data_viewers.viewer1Dbasic import Viewer1DBasic
|
|
18
|
+
from pymodaq.utils import daq_utils as utils
|
|
19
|
+
from pymodaq.utils.messenger import deprecation_msg
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Point:
|
|
23
|
+
def __init__(self, *elt: IterableType[float]):
|
|
24
|
+
"""Initialize a geometric point in an arbitrary number of dimensions
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
elt: either a tuple of floats, passed as multiple parameters or a single Iterable parameter
|
|
29
|
+
"""
|
|
30
|
+
if len(elt) == 1 and isinstance(elt[0], Iterable):
|
|
31
|
+
elt = elt[0]
|
|
32
|
+
|
|
33
|
+
self._coordinates = np.atleast_1d(np.squeeze(elt))
|
|
34
|
+
self._ndim = len(elt)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def coordinates(self):
|
|
38
|
+
return self._coordinates
|
|
39
|
+
|
|
40
|
+
def copy(self):
|
|
41
|
+
return Point(self.coordinates.copy())
|
|
42
|
+
|
|
43
|
+
def __getitem__(self, item: int):
|
|
44
|
+
return self._coordinates[item]
|
|
45
|
+
|
|
46
|
+
def __setitem__(self, key: int, value: float):
|
|
47
|
+
self._coordinates[key] = value
|
|
48
|
+
|
|
49
|
+
def __len__(self):
|
|
50
|
+
return self._ndim
|
|
51
|
+
|
|
52
|
+
def _compare_length(self, other: 'Point'):
|
|
53
|
+
if len(self) != len(other):
|
|
54
|
+
raise ValueError('Those points should be expressed in the same coordinate system and dimensions')
|
|
55
|
+
|
|
56
|
+
def __add__(self, other: Union['Point', 'Vector']):
|
|
57
|
+
self._compare_length(other)
|
|
58
|
+
return Point(*(self._coordinates + other._coordinates))
|
|
59
|
+
|
|
60
|
+
def __sub__(self, other: 'Point'):
|
|
61
|
+
self._compare_length(other)
|
|
62
|
+
return Point(*(self._coordinates - other._coordinates))
|
|
63
|
+
|
|
64
|
+
def __repr__(self):
|
|
65
|
+
return f'Point({self.coordinates})'
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Vector:
|
|
69
|
+
def __init__(self, coordinates: Union[Point, np.ndarray], origin: Point = None):
|
|
70
|
+
if isinstance(coordinates, Point):
|
|
71
|
+
self._coordinates = coordinates.coordinates
|
|
72
|
+
else:
|
|
73
|
+
self._coordinates = coordinates
|
|
74
|
+
|
|
75
|
+
if origin is None:
|
|
76
|
+
origin = np.zeros((len(coordinates)))
|
|
77
|
+
else:
|
|
78
|
+
self._compare_length(origin)
|
|
79
|
+
|
|
80
|
+
self._origin = origin
|
|
81
|
+
|
|
82
|
+
def _compare_length(self, other: 'Point'):
|
|
83
|
+
if len(self) != len(other):
|
|
84
|
+
raise ValueError('Those Points/Vectors should be expressed in the same coordinate system and dimensions')
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def origin(self):
|
|
88
|
+
return self._origin
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def coordinates(self):
|
|
92
|
+
return self._coordinates
|
|
93
|
+
|
|
94
|
+
def copy(self):
|
|
95
|
+
return Vector(self.coordinates.copy(), origin=self.origin.copy())
|
|
96
|
+
|
|
97
|
+
def __len__(self):
|
|
98
|
+
return len(self._coordinates)
|
|
99
|
+
|
|
100
|
+
def norm(self):
|
|
101
|
+
return np.linalg.norm(self._coordinates)
|
|
102
|
+
|
|
103
|
+
def unit_vector(self):
|
|
104
|
+
return self * (1 / self.norm())
|
|
105
|
+
|
|
106
|
+
def __add__(self, other: 'Vector'):
|
|
107
|
+
self._compare_length(other)
|
|
108
|
+
return Vector(self.coordinates + other.coordinates, origin=self.origin.copy())
|
|
109
|
+
|
|
110
|
+
def __sub__(self, other: 'Vector'):
|
|
111
|
+
self._compare_length(other)
|
|
112
|
+
return Vector(self.coordinates - other.coordinates, origin=self.origin.copy())
|
|
113
|
+
|
|
114
|
+
def __mul__(self, other: Number):
|
|
115
|
+
if not isinstance(other, Number):
|
|
116
|
+
raise TypeError(f'Cannot multiply a vector with {other}')
|
|
117
|
+
return Vector(other * self.coordinates, origin=self.origin.copy())
|
|
118
|
+
|
|
119
|
+
def dot(self, other: 'Vector'):
|
|
120
|
+
self._compare_length(other)
|
|
121
|
+
return np.dot(self.coordinates, other.coordinates)
|
|
122
|
+
|
|
123
|
+
def cross(self, other: 'Vector'):
|
|
124
|
+
self._compare_length(other)
|
|
125
|
+
return np.cross(self.coordinates, other.coordinates)
|
|
126
|
+
|
|
127
|
+
def __repr__(self):
|
|
128
|
+
return f'Vector({self.coordinates})/Origin({self.origin.coordinates})'
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_sub_segmented_positions(spacing: float, points: List[Point]) -> List[np.ndarray]:
|
|
132
|
+
"""Get Points coordinates spaced in between subsequent Points
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
spacing: float
|
|
137
|
+
Distance between two subpoints
|
|
138
|
+
points: List[Point]
|
|
139
|
+
List of Points in arbitrary dimension forming segments one want to sample with a distance equal to spacing
|
|
140
|
+
|
|
141
|
+
Returns
|
|
142
|
+
-------
|
|
143
|
+
List[np.ndarray]: The list of the coordinates of the points
|
|
144
|
+
"""
|
|
145
|
+
positions = []
|
|
146
|
+
for ind in range(len(points) - 1):
|
|
147
|
+
vect = Vector(points[ind+1]-points[ind], origin=points[ind])
|
|
148
|
+
npts = 0
|
|
149
|
+
while npts * spacing < vect.norm():
|
|
150
|
+
positions.append(
|
|
151
|
+
(vect.origin + vect.unit_vector() * npts * spacing).coordinates)
|
|
152
|
+
npts += 1
|
|
153
|
+
|
|
154
|
+
# # add_last point not taken into account
|
|
155
|
+
positions.append(points[-1].coordinates)
|
|
156
|
+
return positions
|
|
157
|
+
|
|
12
158
|
|
|
13
159
|
class QVector(QtCore.QLineF):
|
|
14
160
|
def __init__(self, *elt):
|
|
@@ -253,13 +399,35 @@ def makePolygons(tri):
|
|
|
253
399
|
|
|
254
400
|
|
|
255
401
|
class Data0DWithHistory:
|
|
402
|
+
"""Object to store scalar values and keep a history of a given length to them"""
|
|
256
403
|
def __init__(self, Nsamples=200):
|
|
257
404
|
super().__init__()
|
|
258
405
|
self._datas = dict([])
|
|
259
|
-
self.
|
|
406
|
+
self._Nsamples = Nsamples
|
|
260
407
|
self._xaxis = None
|
|
261
408
|
self._data_length = 0
|
|
262
409
|
|
|
410
|
+
@property
|
|
411
|
+
def size(self):
|
|
412
|
+
return self._data_length
|
|
413
|
+
|
|
414
|
+
@property
|
|
415
|
+
def length(self):
|
|
416
|
+
return self._Nsamples
|
|
417
|
+
|
|
418
|
+
@length.setter
|
|
419
|
+
def length(self, history_length: int):
|
|
420
|
+
if history_length > 0:
|
|
421
|
+
self._Nsamples = history_length
|
|
422
|
+
|
|
423
|
+
def __len__(self):
|
|
424
|
+
return self.length
|
|
425
|
+
|
|
426
|
+
@dispatch(data_mod.DataWithAxes)
|
|
427
|
+
def add_datas(self, data: data_mod.DataRaw):
|
|
428
|
+
datas = {data.labels[ind]: data.data[ind] for ind in range(len(data))}
|
|
429
|
+
self.add_datas(datas)
|
|
430
|
+
|
|
263
431
|
@dispatch(list)
|
|
264
432
|
def add_datas(self, datas: list):
|
|
265
433
|
"""
|
|
@@ -279,12 +447,12 @@ class Data0DWithHistory:
|
|
|
279
447
|
----------
|
|
280
448
|
datas: (dict) dictionaary of floats or np.array(float)
|
|
281
449
|
"""
|
|
282
|
-
if
|
|
450
|
+
if datas.keys() != self._datas.keys():
|
|
283
451
|
self.clear_data()
|
|
284
452
|
|
|
285
453
|
self._data_length += 1
|
|
286
454
|
|
|
287
|
-
if self._data_length > self.
|
|
455
|
+
if self._data_length > self._Nsamples:
|
|
288
456
|
self._xaxis += 1
|
|
289
457
|
else:
|
|
290
458
|
self._xaxis = np.linspace(0, self._data_length, self._data_length, endpoint=False)
|
|
@@ -298,7 +466,7 @@ class Data0DWithHistory:
|
|
|
298
466
|
else:
|
|
299
467
|
self._datas[data_key] = np.concatenate((self._datas[data_key], data))
|
|
300
468
|
|
|
301
|
-
if self._data_length > self.
|
|
469
|
+
if self._data_length > self._Nsamples:
|
|
302
470
|
self._datas[data_key] = self._datas[data_key][1:]
|
|
303
471
|
|
|
304
472
|
@property
|
|
@@ -315,76 +483,20 @@ class Data0DWithHistory:
|
|
|
315
483
|
self._xaxis = np.array([])
|
|
316
484
|
|
|
317
485
|
|
|
318
|
-
class
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
if
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
offset = np.max(data)
|
|
336
|
-
|
|
337
|
-
return scaling, offset, label, units
|
|
338
|
-
|
|
339
|
-
@staticmethod
|
|
340
|
-
@dispatch(utils.Axis)
|
|
341
|
-
def extract_axis_info(axis: utils.Axis):
|
|
342
|
-
data = None
|
|
343
|
-
if 'data' in axis:
|
|
344
|
-
data = axis['data']
|
|
345
|
-
label = axis['label']
|
|
346
|
-
units = axis['units']
|
|
347
|
-
|
|
348
|
-
scaling = 1
|
|
349
|
-
offset = 0
|
|
350
|
-
if data is not None:
|
|
351
|
-
if len(data) > 1:
|
|
352
|
-
scaling = data[1] - data[0]
|
|
353
|
-
if scaling > 0:
|
|
354
|
-
offset = np.min(data)
|
|
355
|
-
else:
|
|
356
|
-
offset = np.max(data)
|
|
357
|
-
|
|
358
|
-
return scaling, offset, label, units
|
|
359
|
-
|
|
360
|
-
@staticmethod
|
|
361
|
-
@dispatch(edict)
|
|
362
|
-
def extract_axis_info(axis: edict):
|
|
363
|
-
deprecation_msg('edict should not be used to store axis info, use daq_utils.Axis')
|
|
364
|
-
data = None
|
|
365
|
-
if 'data' in axis:
|
|
366
|
-
data = axis['data']
|
|
367
|
-
label = axis['label']
|
|
368
|
-
units = axis['units']
|
|
369
|
-
|
|
370
|
-
scaling = 1
|
|
371
|
-
offset = 0
|
|
372
|
-
if data is not None:
|
|
373
|
-
if len(data) > 1:
|
|
374
|
-
scaling = data[1] - data[0]
|
|
375
|
-
if scaling > 0:
|
|
376
|
-
offset = np.min(data)
|
|
377
|
-
else:
|
|
378
|
-
offset = np.max(data)
|
|
379
|
-
|
|
380
|
-
return scaling, offset, label, units
|
|
381
|
-
|
|
382
|
-
@staticmethod
|
|
383
|
-
@dispatch(AxisItem_Scaled)
|
|
384
|
-
def extract_axis_info(axis: AxisItem_Scaled):
|
|
385
|
-
label = axis.axis_label
|
|
386
|
-
units = axis.axis_units
|
|
387
|
-
scaling = axis.axis_scaling
|
|
388
|
-
offset = axis.axis_offset
|
|
389
|
-
|
|
390
|
-
return scaling, offset, label, units
|
|
486
|
+
class View_cust(pg.ViewBox):
|
|
487
|
+
"""Custom ViewBox used to enable other properties compared to parent class: pg.ViewBox
|
|
488
|
+
|
|
489
|
+
"""
|
|
490
|
+
sig_double_clicked = QtCore.Signal(float, float)
|
|
491
|
+
|
|
492
|
+
def __init__(self, parent=None, border=None, lockAspect=False, enableMouse=True, invertY=False,
|
|
493
|
+
enableMenu=True, name=None, invertX=False):
|
|
494
|
+
super().__init__(parent, border, lockAspect, enableMouse, invertY, enableMenu, name, invertX)
|
|
495
|
+
|
|
496
|
+
def mouseClickEvent(self, ev):
|
|
497
|
+
if ev.button() == QtCore.Qt.RightButton and self.menuEnabled():
|
|
498
|
+
ev.accept()
|
|
499
|
+
self.raiseContextMenu(ev)
|
|
500
|
+
if ev.double():
|
|
501
|
+
pos = self.mapToView(ev.pos())
|
|
502
|
+
self.sig_double_clicked.emit(pos.x(), pos.y())
|
|
@@ -10,7 +10,7 @@ import collections
|
|
|
10
10
|
import copy
|
|
11
11
|
|
|
12
12
|
import math
|
|
13
|
-
from pymodaq.
|
|
13
|
+
from pymodaq.utils import daq_utils as utils
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
# %%
|
|
@@ -61,7 +61,7 @@ def isfloat(number):
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
def iterable_not_string(thing):
|
|
64
|
-
return isinstance(thing, collections.Iterable) and not isinstance(thing, str)
|
|
64
|
+
return isinstance(thing, collections.abc.Iterable) and not isinstance(thing, str)
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
class SpecialSlicers(object):
|
|
@@ -390,16 +390,6 @@ class DataAxis(object):
|
|
|
390
390
|
|
|
391
391
|
return my_slice
|
|
392
392
|
|
|
393
|
-
@property
|
|
394
|
-
def index_in_array(self):
|
|
395
|
-
if self.axes_manager is not None:
|
|
396
|
-
return self.axes_manager._axes.index(self)
|
|
397
|
-
else:
|
|
398
|
-
raise AttributeError(
|
|
399
|
-
"This DataAxis does not belong to an AxesManager"
|
|
400
|
-
" and therefore its index_in_array attribute "
|
|
401
|
-
" is not defined")
|
|
402
|
-
|
|
403
393
|
def value2index(self, value, rounding=round):
|
|
404
394
|
"""Return the closest index to the given value if between the limit.
|
|
405
395
|
|
|
@@ -741,7 +731,7 @@ class AxesManager(object):
|
|
|
741
731
|
|
|
742
732
|
class Signal(FancySlicing):
|
|
743
733
|
|
|
744
|
-
def __init__(self, data, **kwds):
|
|
734
|
+
def __init__(self, data: np.ndarray, **kwds):
|
|
745
735
|
"""Create a Signal from a numpy array.
|
|
746
736
|
|
|
747
737
|
Parameters
|
|
@@ -761,6 +751,20 @@ class Signal(FancySlicing):
|
|
|
761
751
|
self.inav = SpecialSlicersSignal(self, True)
|
|
762
752
|
self.isig = SpecialSlicersSignal(self, False)
|
|
763
753
|
|
|
754
|
+
def get_data_dimension(self):
|
|
755
|
+
dimension = "("
|
|
756
|
+
for ind, ax in enumerate(self.axes_manager.navigation_shape):
|
|
757
|
+
if ind != len(self.axes_manager.navigation_shape) - 1:
|
|
758
|
+
dimension += str(ax) + ','
|
|
759
|
+
else:
|
|
760
|
+
dimension += str(ax) + '|'
|
|
761
|
+
for ind, ax in enumerate(self.axes_manager.signal_shape):
|
|
762
|
+
if ind != len(self.axes_manager.signal_shape) - 1:
|
|
763
|
+
dimension += str(ax) + ','
|
|
764
|
+
else:
|
|
765
|
+
dimension += str(ax) + ')'
|
|
766
|
+
return dimension
|
|
767
|
+
|
|
764
768
|
def _remove_axis(self, axes):
|
|
765
769
|
am = self.axes_manager
|
|
766
770
|
axes = am[axes]
|
|
@@ -789,6 +793,10 @@ class Signal(FancySlicing):
|
|
|
789
793
|
def data(self, value):
|
|
790
794
|
self._data = np.atleast_1d(np.asanyarray(value))
|
|
791
795
|
|
|
796
|
+
@property
|
|
797
|
+
def shape(self):
|
|
798
|
+
return self._data.shape
|
|
799
|
+
|
|
792
800
|
def __repr__(self):
|
|
793
801
|
unfolded = ""
|
|
794
802
|
string = '<'
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created the 04/11/2022
|
|
4
|
+
|
|
5
|
+
@author: Sebastien Weber
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pyqtgraph as pg
|
|
9
|
+
from qtpy import QtWidgets
|
|
10
|
+
|
|
11
|
+
from pymodaq.utils.plotting.utils.plot_utils import View_cust
|
|
12
|
+
from pymodaq.utils.plotting.items.axis_scaled import AXIS_POSITIONS, AxisItem_Scaled
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ImageWidget(pg.GraphicsLayoutWidget):
|
|
16
|
+
"""this gives a layout to add imageitems.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, parent=None, *args_plotitem, **kwargs_plotitem):
|
|
20
|
+
|
|
21
|
+
super().__init__(parent)
|
|
22
|
+
self.setupUI(*args_plotitem, **kwargs_plotitem)
|
|
23
|
+
|
|
24
|
+
def setAspectLocked(self, lock=True, ratio=1):
|
|
25
|
+
"""
|
|
26
|
+
Defines the aspect ratio of the view
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
lock: (bool) if True aspect ratio is set to ratio, else the aspect ratio is varying when scaling the view
|
|
30
|
+
ratio: (int) aspect ratio between horizontal and vertical axis
|
|
31
|
+
"""
|
|
32
|
+
self.plotitem.vb.setAspectLocked(lock=True, ratio=1)
|
|
33
|
+
|
|
34
|
+
def getAxis(self, position):
|
|
35
|
+
return self.plotitem.getAxis(position)
|
|
36
|
+
|
|
37
|
+
def setupUI(self, *args_plotitem, **kwargs_plotitem):
|
|
38
|
+
layout = QtWidgets.QGridLayout()
|
|
39
|
+
# set viewer area
|
|
40
|
+
self.scene_obj = self.scene()
|
|
41
|
+
self.view = View_cust()
|
|
42
|
+
self.plotitem = pg.PlotItem(viewBox=self.view, *args_plotitem, **kwargs_plotitem)
|
|
43
|
+
self.plotItem = self.plotitem # for backcompatibility
|
|
44
|
+
self.setAspectLocked(lock=True, ratio=1)
|
|
45
|
+
self.setCentralItem(self.plotitem)
|
|
46
|
+
|
|
47
|
+
def add_scaled_axis(self, position):
|
|
48
|
+
"""
|
|
49
|
+
Add a AxisItem_Scaled to the given position with respect with the plotitem
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
position: (str) either 'top', 'bottom', 'right' or 'left'
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
if position not in AXIS_POSITIONS:
|
|
59
|
+
raise ValueError(f'The Axis position {position} should be in {AXIS_POSITIONS}')
|
|
60
|
+
axis = AxisItem_Scaled(position)
|
|
61
|
+
self.plotitem.setAxisItems({position: axis})
|
|
62
|
+
return axis
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class PlotWidget(pg.PlotWidget):
|
|
66
|
+
def __init__(self, *args, **kwargs):
|
|
67
|
+
plot_item = pg.PlotItem(viewBox=View_cust())
|
|
68
|
+
super().__init__(*args, plotItem=plot_item, **kwargs)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def view(self):
|
|
72
|
+
return self.getViewBox()
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def legend(self):
|
|
76
|
+
return self.plotItem.legend
|