pymodaq 5.1.6__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.
- pymodaq/__init__.py +98 -0
- pymodaq/control_modules/__init__.py +1 -0
- pymodaq/control_modules/daq_move.py +1238 -0
- pymodaq/control_modules/daq_move_ui/__init__.py +0 -0
- pymodaq/control_modules/daq_move_ui/factory.py +48 -0
- pymodaq/control_modules/daq_move_ui/ui_base.py +359 -0
- pymodaq/control_modules/daq_move_ui/uis/__init__.py +0 -0
- pymodaq/control_modules/daq_move_ui/uis/binary.py +139 -0
- pymodaq/control_modules/daq_move_ui/uis/original.py +120 -0
- pymodaq/control_modules/daq_move_ui/uis/relative.py +124 -0
- pymodaq/control_modules/daq_move_ui/uis/simple.py +126 -0
- pymodaq/control_modules/daq_viewer.py +1517 -0
- pymodaq/control_modules/daq_viewer_ui.py +407 -0
- pymodaq/control_modules/mocks.py +57 -0
- pymodaq/control_modules/move_utility_classes.py +1141 -0
- pymodaq/control_modules/thread_commands.py +137 -0
- pymodaq/control_modules/ui_utils.py +72 -0
- pymodaq/control_modules/utils.py +591 -0
- pymodaq/control_modules/viewer_utility_classes.py +670 -0
- pymodaq/daq_utils/__init__.py +0 -0
- pymodaq/daq_utils/daq_utils.py +6 -0
- pymodaq/dashboard.py +2396 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.aliases +3 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvlps +3 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvproj +32 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_1Dgaussian.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_2Dgaussian.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_cmd.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_float.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_int.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_data.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_int.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_scalar.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_string.vi +0 -0
- pymodaq/examples/Labview_TCP_Client/client_state.ctl +0 -0
- pymodaq/examples/Labview_TCP_Client/cmd_types.ctl +0 -0
- pymodaq/examples/__init__.py +0 -0
- pymodaq/examples/function_plotter.py +160 -0
- pymodaq/examples/nonlinearscanner.py +126 -0
- pymodaq/examples/qt_less_standalone_module.py +165 -0
- pymodaq/examples/tcp_client.py +97 -0
- pymodaq/extensions/__init__.py +25 -0
- pymodaq/extensions/adaptive/__init__.py +2 -0
- pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
- pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
- pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
- pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
- pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
- pymodaq/extensions/adaptive/utils.py +123 -0
- pymodaq/extensions/bayesian/__init__.py +2 -0
- pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
- pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
- pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
- pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
- pymodaq/extensions/bayesian/utils.py +180 -0
- pymodaq/extensions/console.py +73 -0
- pymodaq/extensions/daq_logger/__init__.py +1 -0
- pymodaq/extensions/daq_logger/abstract.py +52 -0
- pymodaq/extensions/daq_logger/daq_logger.py +519 -0
- pymodaq/extensions/daq_logger/db/__init__.py +0 -0
- pymodaq/extensions/daq_logger/db/db_logger.py +300 -0
- pymodaq/extensions/daq_logger/db/db_logger_models.py +100 -0
- pymodaq/extensions/daq_logger/h5logging.py +84 -0
- pymodaq/extensions/daq_scan.py +1218 -0
- pymodaq/extensions/daq_scan_ui.py +241 -0
- pymodaq/extensions/data_mixer/__init__.py +0 -0
- pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
- pymodaq/extensions/data_mixer/data_mixer.py +262 -0
- pymodaq/extensions/data_mixer/model.py +108 -0
- pymodaq/extensions/data_mixer/models/__init__.py +0 -0
- pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
- pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
- pymodaq/extensions/data_mixer/parser.py +53 -0
- pymodaq/extensions/data_mixer/utils.py +23 -0
- pymodaq/extensions/h5browser.py +9 -0
- pymodaq/extensions/optimizers_base/__init__.py +0 -0
- pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
- pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
- pymodaq/extensions/optimizers_base/utils.py +427 -0
- pymodaq/extensions/pid/__init__.py +16 -0
- pymodaq/extensions/pid/actuator_controller.py +14 -0
- pymodaq/extensions/pid/daq_move_PID.py +154 -0
- pymodaq/extensions/pid/pid_controller.py +1016 -0
- pymodaq/extensions/pid/utils.py +189 -0
- pymodaq/extensions/utils.py +111 -0
- pymodaq/icon.ico +0 -0
- pymodaq/post_treatment/__init__.py +6 -0
- pymodaq/post_treatment/load_and_plot.py +352 -0
- pymodaq/resources/__init__.py +0 -0
- pymodaq/resources/config_template.toml +57 -0
- pymodaq/resources/preset_default.xml +1 -0
- pymodaq/resources/setup_plugin.py +73 -0
- pymodaq/splash.png +0 -0
- pymodaq/utils/__init__.py +0 -0
- pymodaq/utils/array_manipulation.py +6 -0
- pymodaq/utils/calibration_camera.py +180 -0
- pymodaq/utils/chrono_timer.py +203 -0
- pymodaq/utils/config.py +53 -0
- pymodaq/utils/conftests.py +5 -0
- pymodaq/utils/daq_utils.py +158 -0
- pymodaq/utils/data.py +128 -0
- pymodaq/utils/enums.py +6 -0
- pymodaq/utils/exceptions.py +38 -0
- pymodaq/utils/gui_utils/__init__.py +10 -0
- pymodaq/utils/gui_utils/loader_utils.py +75 -0
- pymodaq/utils/gui_utils/utils.py +18 -0
- pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
- pymodaq/utils/h5modules/__init__.py +2 -0
- pymodaq/utils/h5modules/module_saving.py +526 -0
- pymodaq/utils/leco/__init__.py +25 -0
- pymodaq/utils/leco/daq_move_LECODirector.py +217 -0
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +163 -0
- pymodaq/utils/leco/director_utils.py +74 -0
- pymodaq/utils/leco/leco_director.py +166 -0
- pymodaq/utils/leco/pymodaq_listener.py +364 -0
- pymodaq/utils/leco/rpc_method_definitions.py +43 -0
- pymodaq/utils/leco/utils.py +74 -0
- pymodaq/utils/logger.py +6 -0
- pymodaq/utils/managers/__init__.py +0 -0
- pymodaq/utils/managers/batchscan_manager.py +346 -0
- pymodaq/utils/managers/modules_manager.py +589 -0
- pymodaq/utils/managers/overshoot_manager.py +242 -0
- pymodaq/utils/managers/preset_manager.py +229 -0
- pymodaq/utils/managers/preset_manager_utils.py +262 -0
- pymodaq/utils/managers/remote_manager.py +484 -0
- pymodaq/utils/math_utils.py +6 -0
- pymodaq/utils/messenger.py +6 -0
- pymodaq/utils/parameter/__init__.py +10 -0
- pymodaq/utils/parameter/utils.py +6 -0
- pymodaq/utils/scanner/__init__.py +5 -0
- pymodaq/utils/scanner/scan_config.py +16 -0
- pymodaq/utils/scanner/scan_factory.py +259 -0
- pymodaq/utils/scanner/scan_selector.py +477 -0
- pymodaq/utils/scanner/scanner.py +324 -0
- pymodaq/utils/scanner/scanners/_1d_scanners.py +174 -0
- pymodaq/utils/scanner/scanners/_2d_scanners.py +299 -0
- pymodaq/utils/scanner/scanners/__init__.py +1 -0
- pymodaq/utils/scanner/scanners/sequential.py +224 -0
- pymodaq/utils/scanner/scanners/tabular.py +319 -0
- pymodaq/utils/scanner/utils.py +110 -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 +50 -0
- pymodaq/utils/tcp_ip/__init__.py +6 -0
- pymodaq/utils/tcp_ip/mysocket.py +12 -0
- pymodaq/utils/tcp_ip/serializer.py +13 -0
- pymodaq/utils/tcp_ip/tcp_server_client.py +772 -0
- pymodaq-5.1.6.dist-info/METADATA +238 -0
- pymodaq-5.1.6.dist-info/RECORD +154 -0
- pymodaq-5.1.6.dist-info/WHEEL +4 -0
- pymodaq-5.1.6.dist-info/entry_points.txt +7 -0
- pymodaq-5.1.6.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from collections import OrderedDict
|
|
3
|
+
import importlib
|
|
4
|
+
import time
|
|
5
|
+
import sys
|
|
6
|
+
from typing import List, Dict
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from qtpy import QtWidgets, QtCore
|
|
10
|
+
from qtpy.QtCore import QObject, Slot, QThread, Signal
|
|
11
|
+
|
|
12
|
+
from pyqtgraph import ROI, RectROI, PolyLineROI, Point, LinearRegionItem
|
|
13
|
+
|
|
14
|
+
from pymodaq_utils.factory import ObjectFactory
|
|
15
|
+
from pymodaq_utils.logger import set_logger, get_module_name
|
|
16
|
+
from pymodaq_utils import utils
|
|
17
|
+
|
|
18
|
+
from pymodaq_gui.managers.parameter_manager import ParameterManager
|
|
19
|
+
from pymodaq_gui import utils as gutils
|
|
20
|
+
from pymodaq_gui.utils import DockArea, Dock
|
|
21
|
+
from pymodaq_gui.plotting.utils.plot_utils import QVector
|
|
22
|
+
from pymodaq_gui.parameter.pymodaq_ptypes import TableViewCustom
|
|
23
|
+
from pymodaq_gui.parameter import utils as putils
|
|
24
|
+
from pymodaq_gui.plotting.data_viewers.viewer import ViewerBase
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
logger = set_logger(get_module_name(__file__))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Selector:
|
|
31
|
+
"""Base class defining the interface for a Selector"""
|
|
32
|
+
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def get_header(self):
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
def get_coordinates(self) -> np.ndarray:
|
|
39
|
+
"""Returns coordinates as a ndarray
|
|
40
|
+
|
|
41
|
+
Particular implementation and returned array shape depends on the selector.
|
|
42
|
+
"""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def set_coordinates(self, coordinates: np.ndarray):
|
|
47
|
+
"""Set the coordinates of the selector using the input ndarray
|
|
48
|
+
|
|
49
|
+
Particular implementation depends on the selector.
|
|
50
|
+
"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class SelectorFactory(ObjectFactory):
|
|
55
|
+
"""Factory class registering and storing Selectors"""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@SelectorFactory.register('PolyLines')
|
|
59
|
+
class PolyLineROI(Selector, PolyLineROI):
|
|
60
|
+
|
|
61
|
+
def __init__(self, *args, **kwargs):
|
|
62
|
+
super().__init__(positions=[(0, 0), (10, 10)], *args, **kwargs)
|
|
63
|
+
|
|
64
|
+
def get_header(self):
|
|
65
|
+
return ['x', 'y']
|
|
66
|
+
|
|
67
|
+
def get_coordinates(self) -> np.ndarray:
|
|
68
|
+
return np.array([[vertex.x(), vertex.y()] for vertex in self.get_vertex()])
|
|
69
|
+
|
|
70
|
+
def set_coordinates(self, coordinates: np.ndarray):
|
|
71
|
+
self.setPoints(coordinates)
|
|
72
|
+
|
|
73
|
+
def get_vertex(self):
|
|
74
|
+
return [h['item'].pos() for h in self.handles]
|
|
75
|
+
|
|
76
|
+
def get_vectors(self):
|
|
77
|
+
imgPts = self.get_vertex()
|
|
78
|
+
d = []
|
|
79
|
+
for i in range(len(imgPts) - 1):
|
|
80
|
+
d.append(QVector(imgPts[i], Point(imgPts[i + 1])))
|
|
81
|
+
return d
|
|
82
|
+
|
|
83
|
+
def getArrayIndexes(self, spacing=1, **kwds):
|
|
84
|
+
imgPts = self.get_vertex()
|
|
85
|
+
positions = []
|
|
86
|
+
for i in range(len(imgPts) - 1):
|
|
87
|
+
d = Point(imgPts[i + 1] - imgPts[i])
|
|
88
|
+
o = Point(imgPts[i])
|
|
89
|
+
vect = Point(d.norm())
|
|
90
|
+
Npts = 0
|
|
91
|
+
while Npts * spacing < d.length():
|
|
92
|
+
positions.append(((o + Npts * spacing * vect).x(), (o + Npts * spacing * vect).y()))
|
|
93
|
+
Npts += 1
|
|
94
|
+
# add_last point not taken into account
|
|
95
|
+
positions.append((imgPts[-1].x(), imgPts[-1].y()))
|
|
96
|
+
return positions
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@SelectorFactory.register('RectangularROI')
|
|
100
|
+
class RectangularRoi(Selector, RectROI):
|
|
101
|
+
|
|
102
|
+
def __init__(self, *args, **kwargs):
|
|
103
|
+
super().__init__([0, 0], [10, 10], *args, invertible=True, **kwargs)
|
|
104
|
+
|
|
105
|
+
def get_header(self):
|
|
106
|
+
return ['x', 'y']
|
|
107
|
+
|
|
108
|
+
def get_coordinates(self) -> np.ndarray:
|
|
109
|
+
"""Returns bottom/left and top/right positions of the Rectangular ROI"""
|
|
110
|
+
coordinates = [[self.pos().x(), self.pos().y()],
|
|
111
|
+
[self.pos().x() + self.size().x(), self.pos().y() + self.size().y()]]
|
|
112
|
+
return np.array(coordinates)
|
|
113
|
+
|
|
114
|
+
def set_coordinates(self, coordinates: np.ndarray):
|
|
115
|
+
if len(coordinates) != 0:
|
|
116
|
+
self.setPos(coordinates[0, :], finish=False)
|
|
117
|
+
self.setSize(coordinates[1, :] - coordinates[0, :])
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@SelectorFactory.register('LinearROI')
|
|
121
|
+
class LinearRegionItem(Selector, LinearRegionItem):
|
|
122
|
+
|
|
123
|
+
def __init__(self, *args, **kwargs):
|
|
124
|
+
super().__init__(*args, **kwargs)
|
|
125
|
+
|
|
126
|
+
def get_header(self):
|
|
127
|
+
return ['x']
|
|
128
|
+
|
|
129
|
+
def get_coordinates(self) -> np.ndarray:
|
|
130
|
+
"""Returns left and right positions of the Linear Region"""
|
|
131
|
+
coordinates = [self.getRegion()]
|
|
132
|
+
return np.array(coordinates).T
|
|
133
|
+
|
|
134
|
+
def set_coordinates(self, coordinates: np.ndarray):
|
|
135
|
+
self.setRegion(coordinates[:, 0])
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class SelectorWrapper(Selector):
|
|
139
|
+
"""Wrapper around real implementation of Selector objects but having the same interface
|
|
140
|
+
|
|
141
|
+
Mandatory because signal can only be emitted with one signature and not with child classes
|
|
142
|
+
Hence this single wrapper of all real implementation of Selector
|
|
143
|
+
"""
|
|
144
|
+
def __init__(self, selector: Selector):
|
|
145
|
+
self._selector: Selector = selector
|
|
146
|
+
|
|
147
|
+
def __call__(self, *args, **kwargs):
|
|
148
|
+
return self._selector
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def name(self):
|
|
152
|
+
return self._selector.__class__
|
|
153
|
+
|
|
154
|
+
def get_header(self):
|
|
155
|
+
return self._selector.get_header()
|
|
156
|
+
|
|
157
|
+
def get_coordinates(self):
|
|
158
|
+
return self._selector.get_coordinates()
|
|
159
|
+
|
|
160
|
+
def set_coordinates(self, coordinates: np.ndarray):
|
|
161
|
+
self._selector.set_coordinates(coordinates)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class TableModel(gutils.TableModel):
|
|
165
|
+
"""Table Model for the Model/View Qt framework dedicated to the Tabular scan mode"""
|
|
166
|
+
def __init__(self, data, header_names=None, **kwargs):
|
|
167
|
+
if header_names is None:
|
|
168
|
+
if 'header' in kwargs: # when saved as XML the header will be saved and restored here
|
|
169
|
+
header_names = [h for h in kwargs['header']]
|
|
170
|
+
kwargs.pop('header')
|
|
171
|
+
else:
|
|
172
|
+
raise Exception('Invalid header')
|
|
173
|
+
|
|
174
|
+
header = [name for name in header_names]
|
|
175
|
+
editable = [True for _ in header_names]
|
|
176
|
+
super().__init__(data, header, editable=editable, **kwargs)
|
|
177
|
+
|
|
178
|
+
def data_as_ndarray(self):
|
|
179
|
+
return np.array(self.raw_data)
|
|
180
|
+
|
|
181
|
+
def __len__(self):
|
|
182
|
+
return len(self._data)
|
|
183
|
+
|
|
184
|
+
def add_data(self, row, data=None):
|
|
185
|
+
if data is not None:
|
|
186
|
+
self.insert_data(row, [float(d) for d in data])
|
|
187
|
+
else:
|
|
188
|
+
self.insert_data(row, [0. for name in self.header])
|
|
189
|
+
|
|
190
|
+
def remove_data(self, row):
|
|
191
|
+
self.remove_row(row)
|
|
192
|
+
|
|
193
|
+
def __repr__(self):
|
|
194
|
+
return f'{self.__class__.__name__} from module {self.__class__.__module__}'
|
|
195
|
+
|
|
196
|
+
def validate_data(self, row, col, value):
|
|
197
|
+
return True
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class SelectorItem:
|
|
201
|
+
"""An object storing a viewer to display selectors and a name to reference it
|
|
202
|
+
|
|
203
|
+
If the name is not given, constructs one from a unique index
|
|
204
|
+
"""
|
|
205
|
+
_index: int = 0
|
|
206
|
+
|
|
207
|
+
def __init__(self, viewer: ViewerBase, name: str = None):
|
|
208
|
+
self.viewer = viewer
|
|
209
|
+
if name is None:
|
|
210
|
+
name = f'{self.viewer.title}_{self._index:03d}'
|
|
211
|
+
self.name = name
|
|
212
|
+
|
|
213
|
+
SelectorItem._index += 1
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
selector_factory = SelectorFactory()
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class ScanSelector(ParameterManager, QObject):
|
|
220
|
+
"""Allows selection of a given 2D viewer to get scan info
|
|
221
|
+
|
|
222
|
+
respectively scan2D or scan Tabular from respectively a rectangular ROI or a polyline
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
viewer_items: dict
|
|
227
|
+
where the keys are the titles of the sources while the values are dict with keys
|
|
228
|
+
* viewers: list of plotitems
|
|
229
|
+
* names: list of viewer titles
|
|
230
|
+
|
|
231
|
+
selector_type: str
|
|
232
|
+
either 'PolyLines' corresponding to a polyline ROI or 'Rectangle' for a rect Roi
|
|
233
|
+
positions: list
|
|
234
|
+
a sequence of 2 floats sequence [(x1,y1),(x2,y2),(x3,y3),...]
|
|
235
|
+
|
|
236
|
+
"""
|
|
237
|
+
scan_select_signal = Signal(SelectorWrapper)
|
|
238
|
+
|
|
239
|
+
params = [
|
|
240
|
+
{'title': 'Scan options', 'name': 'scan_options', 'type': 'group', 'children': [
|
|
241
|
+
{'title': 'Sources:', 'name': 'sources', 'type': 'list', },
|
|
242
|
+
{'title': 'Selector type:', 'name': 'selector_type', 'type': 'list',
|
|
243
|
+
'limits': selector_factory.keys},
|
|
244
|
+
]},
|
|
245
|
+
{'title': 'Coordinates:', 'name': 'coordinates', 'type': 'table_view', 'visible': True,
|
|
246
|
+
'delegate': gutils.SpinBoxDelegate,},
|
|
247
|
+
# ]},
|
|
248
|
+
]
|
|
249
|
+
|
|
250
|
+
def __init__(self, viewer_items: List[SelectorItem] = None, positions: List = None):
|
|
251
|
+
QObject.__init__(self)
|
|
252
|
+
ParameterManager.__init__(self, 'selector_settings')
|
|
253
|
+
|
|
254
|
+
self.table_model: TableModel = None
|
|
255
|
+
self.table_view: TableViewCustom = None
|
|
256
|
+
|
|
257
|
+
self.selector: Selector = None
|
|
258
|
+
self.selector_source: ViewerBase = None
|
|
259
|
+
|
|
260
|
+
self.update_selector_type()
|
|
261
|
+
|
|
262
|
+
if viewer_items is None:
|
|
263
|
+
viewer_items = []
|
|
264
|
+
|
|
265
|
+
self.viewers_items = viewer_items
|
|
266
|
+
self.sources_names = [item.name for item in viewer_items]
|
|
267
|
+
if len(viewer_items) != 0:
|
|
268
|
+
self.selector_source = viewer_items[0].viewer
|
|
269
|
+
else:
|
|
270
|
+
self.selector_source = None
|
|
271
|
+
|
|
272
|
+
# self.remove_selector()
|
|
273
|
+
# self.update_selector_type()
|
|
274
|
+
|
|
275
|
+
if positions is not None:
|
|
276
|
+
self.selector.set_coordinates(positions)
|
|
277
|
+
|
|
278
|
+
@property
|
|
279
|
+
def selector_type(self) -> str:
|
|
280
|
+
return self.settings['scan_options', 'selector_type']
|
|
281
|
+
|
|
282
|
+
@selector_type.setter
|
|
283
|
+
def selector_type(self, selector_type: str):
|
|
284
|
+
if selector_type not in selector_factory.keys:
|
|
285
|
+
raise TypeError(f'{selector_type} is an unknown Selector Type')
|
|
286
|
+
self.settings.child('scan_options', 'selector_type').setValue(selector_type)
|
|
287
|
+
|
|
288
|
+
@property
|
|
289
|
+
def source_name(self) -> str:
|
|
290
|
+
return self.settings['scan_options', 'sources']
|
|
291
|
+
|
|
292
|
+
@source_name.setter
|
|
293
|
+
def source_name(self, source: str):
|
|
294
|
+
if source in self.settings.child('scan_options', 'sources').opts['limits']:
|
|
295
|
+
self.settings.child('scan_options', 'sources').setValue(source)
|
|
296
|
+
|
|
297
|
+
def update_model(self, init_data=None):
|
|
298
|
+
if init_data is None:
|
|
299
|
+
init_data = [[0. for _ in self.selector.get_header()]]
|
|
300
|
+
|
|
301
|
+
self.table_model = TableModel(init_data, self.selector.get_header())
|
|
302
|
+
self.table_view = putils.get_widget_from_tree(self.settings_tree, TableViewCustom)[0]
|
|
303
|
+
self.settings.child('coordinates').setValue(self.table_model)
|
|
304
|
+
self.update_table_view()
|
|
305
|
+
|
|
306
|
+
def update_model_data(self, data: np.ndarray):
|
|
307
|
+
self.table_model.set_data_all(data)
|
|
308
|
+
|
|
309
|
+
def update_table_view(self):
|
|
310
|
+
self.table_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
|
|
311
|
+
self.table_view.horizontalHeader().setStretchLastSection(True)
|
|
312
|
+
self.table_view.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
|
|
313
|
+
self.table_view.setSelectionMode(QtWidgets.QTableView.SingleSelection)
|
|
314
|
+
self.table_view.setItemDelegate(gutils.SpinBoxDelegate())
|
|
315
|
+
|
|
316
|
+
self.table_view.setDragEnabled(False)
|
|
317
|
+
self.table_view.setDropIndicatorShown(False)
|
|
318
|
+
self.table_view.setAcceptDrops(False)
|
|
319
|
+
self.table_view.viewport().setAcceptDrops(False)
|
|
320
|
+
self.table_view.setDefaultDropAction(QtCore.Qt.MoveAction)
|
|
321
|
+
self.table_view.setDragDropMode(QtWidgets.QTableView.InternalMove)
|
|
322
|
+
self.table_view.setDragDropOverwriteMode(False)
|
|
323
|
+
|
|
324
|
+
@property
|
|
325
|
+
def viewers_items(self):
|
|
326
|
+
return self._viewers_items
|
|
327
|
+
|
|
328
|
+
@viewers_items.setter
|
|
329
|
+
def viewers_items(self, items: List[SelectorItem]):
|
|
330
|
+
self._viewers_items = items
|
|
331
|
+
self.sources_names = [item.name for item in items]
|
|
332
|
+
self.selector_source = items[0].viewer
|
|
333
|
+
self.settings.child('scan_options', 'sources').setOpts(limits=self.sources_names)
|
|
334
|
+
|
|
335
|
+
def show(self, visible=True):
|
|
336
|
+
self.show_selector(visible)
|
|
337
|
+
if visible:
|
|
338
|
+
self.widget.show()
|
|
339
|
+
else:
|
|
340
|
+
self.widget.hide()
|
|
341
|
+
|
|
342
|
+
def hide(self):
|
|
343
|
+
self.show(False)
|
|
344
|
+
|
|
345
|
+
def value_changed(self, param):
|
|
346
|
+
|
|
347
|
+
if param.name() == 'sources' and param.value() is not None:
|
|
348
|
+
self.remove_selector()
|
|
349
|
+
self.selector_source = \
|
|
350
|
+
utils.find_objects_in_list_from_attr_name_val(
|
|
351
|
+
self.viewers_items, 'name', param.value(), return_first=True)[0].viewer
|
|
352
|
+
self.update_selector_type()
|
|
353
|
+
|
|
354
|
+
if param.name() == 'selector_type':
|
|
355
|
+
self.update_selector_type()
|
|
356
|
+
self.selector.sigRegionChangeFinished.emit(self.selector)
|
|
357
|
+
|
|
358
|
+
if param.name() == 'coordinates':
|
|
359
|
+
self.selector.set_coordinates(param.value().data_as_ndarray())
|
|
360
|
+
|
|
361
|
+
def remove_selector(self):
|
|
362
|
+
if self.selector_source is not None:
|
|
363
|
+
try:
|
|
364
|
+
self.selector_source.image_widget.plotitem.removeItem(self.selector)
|
|
365
|
+
except Exception as e:
|
|
366
|
+
logger.exception(str(e))
|
|
367
|
+
pass
|
|
368
|
+
|
|
369
|
+
def update_selector_type(self):
|
|
370
|
+
self.remove_selector()
|
|
371
|
+
mod = importlib.import_module('.scan_selector', 'pymodaq.utils.scanner')
|
|
372
|
+
self.selector = selector_factory.create(self.settings['scan_options', 'selector_type'])
|
|
373
|
+
|
|
374
|
+
if self.selector_source is not None and self.selector is not None:
|
|
375
|
+
self.selector.sigRegionChangeFinished.connect(self.update_scan)
|
|
376
|
+
self.selector_source.plotitem.addItem(self.selector)
|
|
377
|
+
self.show_selector()
|
|
378
|
+
self.update_model(self.selector.get_coordinates())
|
|
379
|
+
|
|
380
|
+
def show_selector(self, visible=True):
|
|
381
|
+
self.selector.setVisible(visible)
|
|
382
|
+
|
|
383
|
+
def update_scan(self):
|
|
384
|
+
if self.selector_source is not None:
|
|
385
|
+
self.update_model_data(self.selector.get_coordinates())
|
|
386
|
+
self.scan_select_signal.emit(SelectorWrapper(self.selector))
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def main_fake_scan():
|
|
390
|
+
from pymodaq.utils.plotting.data_viewers.viewer2D import Viewer2D
|
|
391
|
+
from pymodaq.control_modules.daq_viewer import DAQ_Viewer
|
|
392
|
+
|
|
393
|
+
class UI:
|
|
394
|
+
def __init__(self):
|
|
395
|
+
pass
|
|
396
|
+
|
|
397
|
+
class FakeDaqScan:
|
|
398
|
+
|
|
399
|
+
def __init__(self, area):
|
|
400
|
+
self.area = area
|
|
401
|
+
self.detector_modules = None
|
|
402
|
+
self.ui = UI()
|
|
403
|
+
self.dock = Dock('2D scan', size=(500, 300), closable=False)
|
|
404
|
+
|
|
405
|
+
form = QtWidgets.QWidget()
|
|
406
|
+
self.ui.scan2D_graph = Viewer2D(form)
|
|
407
|
+
self.dock.addWidget(form)
|
|
408
|
+
self.area.addDock(self.dock)
|
|
409
|
+
|
|
410
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
411
|
+
win = QtWidgets.QMainWindow()
|
|
412
|
+
area = DockArea()
|
|
413
|
+
|
|
414
|
+
win.setCentralWidget(area)
|
|
415
|
+
win.resize(1000, 500)
|
|
416
|
+
win.setWindowTitle('pymodaq main')
|
|
417
|
+
fake = FakeDaqScan(area)
|
|
418
|
+
|
|
419
|
+
prog = DAQ_Viewer(area, title="Testing", daq_type='DAQ2D')#, parent_scan=fake)
|
|
420
|
+
prog.init_hardware_ui(True)
|
|
421
|
+
QThread.msleep(1000)
|
|
422
|
+
QtWidgets.QApplication.processEvents()
|
|
423
|
+
prog2 = DAQ_Viewer(area, title="Testing2", daq_type='DAQ2D')#, parent_scan=fake)
|
|
424
|
+
prog2.init_hardware_ui(True)
|
|
425
|
+
QThread.msleep(1000)
|
|
426
|
+
QtWidgets.QApplication.processEvents()
|
|
427
|
+
|
|
428
|
+
fake.detector_modules = [prog, prog2]
|
|
429
|
+
items = OrderedDict()
|
|
430
|
+
items[prog.title] = dict(viewers=[view for view in prog.ui.viewers],
|
|
431
|
+
names=[view.title for view in prog.ui.viewers],
|
|
432
|
+
)
|
|
433
|
+
items[prog2.title] = dict(viewers=[view for view in prog2.ui.viewers],
|
|
434
|
+
names=[view.title for view in prog2.ui.viewers])
|
|
435
|
+
items["DaqScan"] = dict(viewers=[fake.ui.scan2D_graph],
|
|
436
|
+
names=["DaqScan"])
|
|
437
|
+
|
|
438
|
+
selector = ScanSelector(items, scan_type='PolyLines', positions=[(10, -10), (4, 4), (80, 50)])
|
|
439
|
+
|
|
440
|
+
win.show()
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def main_navigator():
|
|
444
|
+
from pymodaq.utils.plotting.navigator import Navigator
|
|
445
|
+
from pymodaq.control_modules.daq_viewer import DAQ_Viewer
|
|
446
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
447
|
+
widg = QtWidgets.QWidget()
|
|
448
|
+
navigator = Navigator(widg, h5file_path=r'C:\Data\2023\20230320\Dataset_20230320_001.h5')
|
|
449
|
+
|
|
450
|
+
widg.show()
|
|
451
|
+
navigator.list_2D_scans()
|
|
452
|
+
|
|
453
|
+
win = QtWidgets.QMainWindow()
|
|
454
|
+
area = DockArea()
|
|
455
|
+
win.setCentralWidget(area)
|
|
456
|
+
win.resize(1000, 500)
|
|
457
|
+
win.setWindowTitle('PyMoDAQ Viewer')
|
|
458
|
+
win.show()
|
|
459
|
+
|
|
460
|
+
viewer = DAQ_Viewer(area, title="Testing", daq_type='DAQ2D')
|
|
461
|
+
viewer.init_hardware_ui(True)
|
|
462
|
+
time.sleep(1)
|
|
463
|
+
QtWidgets.QApplication.processEvents()
|
|
464
|
+
|
|
465
|
+
items = [SelectorItem(viewer=navigator.viewer, name="Navigator")]
|
|
466
|
+
for _viewer_dock, _viewer in zip(viewer.viewers_docks, viewer.viewers):
|
|
467
|
+
items.append(SelectorItem(viewer=_viewer, name=_viewer_dock.title()))
|
|
468
|
+
|
|
469
|
+
scan_selector = ScanSelector(viewer_items=items)
|
|
470
|
+
scan_selector.settings_tree.show()
|
|
471
|
+
|
|
472
|
+
sys.exit(app.exec_())
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
if __name__ == '__main__':
|
|
476
|
+
# main_fake_scan()
|
|
477
|
+
main_navigator()
|