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.
Files changed (154) hide show
  1. pymodaq/__init__.py +98 -0
  2. pymodaq/control_modules/__init__.py +1 -0
  3. pymodaq/control_modules/daq_move.py +1238 -0
  4. pymodaq/control_modules/daq_move_ui/__init__.py +0 -0
  5. pymodaq/control_modules/daq_move_ui/factory.py +48 -0
  6. pymodaq/control_modules/daq_move_ui/ui_base.py +359 -0
  7. pymodaq/control_modules/daq_move_ui/uis/__init__.py +0 -0
  8. pymodaq/control_modules/daq_move_ui/uis/binary.py +139 -0
  9. pymodaq/control_modules/daq_move_ui/uis/original.py +120 -0
  10. pymodaq/control_modules/daq_move_ui/uis/relative.py +124 -0
  11. pymodaq/control_modules/daq_move_ui/uis/simple.py +126 -0
  12. pymodaq/control_modules/daq_viewer.py +1517 -0
  13. pymodaq/control_modules/daq_viewer_ui.py +407 -0
  14. pymodaq/control_modules/mocks.py +57 -0
  15. pymodaq/control_modules/move_utility_classes.py +1141 -0
  16. pymodaq/control_modules/thread_commands.py +137 -0
  17. pymodaq/control_modules/ui_utils.py +72 -0
  18. pymodaq/control_modules/utils.py +591 -0
  19. pymodaq/control_modules/viewer_utility_classes.py +670 -0
  20. pymodaq/daq_utils/__init__.py +0 -0
  21. pymodaq/daq_utils/daq_utils.py +6 -0
  22. pymodaq/dashboard.py +2396 -0
  23. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.aliases +3 -0
  24. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvlps +3 -0
  25. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvproj +32 -0
  26. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.vi +0 -0
  27. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_1Dgaussian.vi +0 -0
  28. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_2Dgaussian.vi +0 -0
  29. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_cmd.vi +0 -0
  30. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_float.vi +0 -0
  31. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_int.vi +0 -0
  32. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_data.vi +0 -0
  33. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_int.vi +0 -0
  34. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_scalar.vi +0 -0
  35. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_string.vi +0 -0
  36. pymodaq/examples/Labview_TCP_Client/client_state.ctl +0 -0
  37. pymodaq/examples/Labview_TCP_Client/cmd_types.ctl +0 -0
  38. pymodaq/examples/__init__.py +0 -0
  39. pymodaq/examples/function_plotter.py +160 -0
  40. pymodaq/examples/nonlinearscanner.py +126 -0
  41. pymodaq/examples/qt_less_standalone_module.py +165 -0
  42. pymodaq/examples/tcp_client.py +97 -0
  43. pymodaq/extensions/__init__.py +25 -0
  44. pymodaq/extensions/adaptive/__init__.py +2 -0
  45. pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
  46. pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
  47. pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
  48. pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
  49. pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
  50. pymodaq/extensions/adaptive/utils.py +123 -0
  51. pymodaq/extensions/bayesian/__init__.py +2 -0
  52. pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
  53. pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
  54. pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
  55. pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
  56. pymodaq/extensions/bayesian/utils.py +180 -0
  57. pymodaq/extensions/console.py +73 -0
  58. pymodaq/extensions/daq_logger/__init__.py +1 -0
  59. pymodaq/extensions/daq_logger/abstract.py +52 -0
  60. pymodaq/extensions/daq_logger/daq_logger.py +519 -0
  61. pymodaq/extensions/daq_logger/db/__init__.py +0 -0
  62. pymodaq/extensions/daq_logger/db/db_logger.py +300 -0
  63. pymodaq/extensions/daq_logger/db/db_logger_models.py +100 -0
  64. pymodaq/extensions/daq_logger/h5logging.py +84 -0
  65. pymodaq/extensions/daq_scan.py +1218 -0
  66. pymodaq/extensions/daq_scan_ui.py +241 -0
  67. pymodaq/extensions/data_mixer/__init__.py +0 -0
  68. pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
  69. pymodaq/extensions/data_mixer/data_mixer.py +262 -0
  70. pymodaq/extensions/data_mixer/model.py +108 -0
  71. pymodaq/extensions/data_mixer/models/__init__.py +0 -0
  72. pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
  73. pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
  74. pymodaq/extensions/data_mixer/parser.py +53 -0
  75. pymodaq/extensions/data_mixer/utils.py +23 -0
  76. pymodaq/extensions/h5browser.py +9 -0
  77. pymodaq/extensions/optimizers_base/__init__.py +0 -0
  78. pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
  79. pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
  80. pymodaq/extensions/optimizers_base/utils.py +427 -0
  81. pymodaq/extensions/pid/__init__.py +16 -0
  82. pymodaq/extensions/pid/actuator_controller.py +14 -0
  83. pymodaq/extensions/pid/daq_move_PID.py +154 -0
  84. pymodaq/extensions/pid/pid_controller.py +1016 -0
  85. pymodaq/extensions/pid/utils.py +189 -0
  86. pymodaq/extensions/utils.py +111 -0
  87. pymodaq/icon.ico +0 -0
  88. pymodaq/post_treatment/__init__.py +6 -0
  89. pymodaq/post_treatment/load_and_plot.py +352 -0
  90. pymodaq/resources/__init__.py +0 -0
  91. pymodaq/resources/config_template.toml +57 -0
  92. pymodaq/resources/preset_default.xml +1 -0
  93. pymodaq/resources/setup_plugin.py +73 -0
  94. pymodaq/splash.png +0 -0
  95. pymodaq/utils/__init__.py +0 -0
  96. pymodaq/utils/array_manipulation.py +6 -0
  97. pymodaq/utils/calibration_camera.py +180 -0
  98. pymodaq/utils/chrono_timer.py +203 -0
  99. pymodaq/utils/config.py +53 -0
  100. pymodaq/utils/conftests.py +5 -0
  101. pymodaq/utils/daq_utils.py +158 -0
  102. pymodaq/utils/data.py +128 -0
  103. pymodaq/utils/enums.py +6 -0
  104. pymodaq/utils/exceptions.py +38 -0
  105. pymodaq/utils/gui_utils/__init__.py +10 -0
  106. pymodaq/utils/gui_utils/loader_utils.py +75 -0
  107. pymodaq/utils/gui_utils/utils.py +18 -0
  108. pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
  109. pymodaq/utils/h5modules/__init__.py +2 -0
  110. pymodaq/utils/h5modules/module_saving.py +526 -0
  111. pymodaq/utils/leco/__init__.py +25 -0
  112. pymodaq/utils/leco/daq_move_LECODirector.py +217 -0
  113. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +163 -0
  114. pymodaq/utils/leco/director_utils.py +74 -0
  115. pymodaq/utils/leco/leco_director.py +166 -0
  116. pymodaq/utils/leco/pymodaq_listener.py +364 -0
  117. pymodaq/utils/leco/rpc_method_definitions.py +43 -0
  118. pymodaq/utils/leco/utils.py +74 -0
  119. pymodaq/utils/logger.py +6 -0
  120. pymodaq/utils/managers/__init__.py +0 -0
  121. pymodaq/utils/managers/batchscan_manager.py +346 -0
  122. pymodaq/utils/managers/modules_manager.py +589 -0
  123. pymodaq/utils/managers/overshoot_manager.py +242 -0
  124. pymodaq/utils/managers/preset_manager.py +229 -0
  125. pymodaq/utils/managers/preset_manager_utils.py +262 -0
  126. pymodaq/utils/managers/remote_manager.py +484 -0
  127. pymodaq/utils/math_utils.py +6 -0
  128. pymodaq/utils/messenger.py +6 -0
  129. pymodaq/utils/parameter/__init__.py +10 -0
  130. pymodaq/utils/parameter/utils.py +6 -0
  131. pymodaq/utils/scanner/__init__.py +5 -0
  132. pymodaq/utils/scanner/scan_config.py +16 -0
  133. pymodaq/utils/scanner/scan_factory.py +259 -0
  134. pymodaq/utils/scanner/scan_selector.py +477 -0
  135. pymodaq/utils/scanner/scanner.py +324 -0
  136. pymodaq/utils/scanner/scanners/_1d_scanners.py +174 -0
  137. pymodaq/utils/scanner/scanners/_2d_scanners.py +299 -0
  138. pymodaq/utils/scanner/scanners/__init__.py +1 -0
  139. pymodaq/utils/scanner/scanners/sequential.py +224 -0
  140. pymodaq/utils/scanner/scanners/tabular.py +319 -0
  141. pymodaq/utils/scanner/utils.py +110 -0
  142. pymodaq/utils/svg/__init__.py +6 -0
  143. pymodaq/utils/svg/svg_renderer.py +20 -0
  144. pymodaq/utils/svg/svg_view.py +35 -0
  145. pymodaq/utils/svg/svg_viewer2D.py +50 -0
  146. pymodaq/utils/tcp_ip/__init__.py +6 -0
  147. pymodaq/utils/tcp_ip/mysocket.py +12 -0
  148. pymodaq/utils/tcp_ip/serializer.py +13 -0
  149. pymodaq/utils/tcp_ip/tcp_server_client.py +772 -0
  150. pymodaq-5.1.6.dist-info/METADATA +238 -0
  151. pymodaq-5.1.6.dist-info/RECORD +154 -0
  152. pymodaq-5.1.6.dist-info/WHEEL +4 -0
  153. pymodaq-5.1.6.dist-info/entry_points.txt +7 -0
  154. pymodaq-5.1.6.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,484 @@
1
+ import os
2
+ import sys
3
+
4
+ from qtpy.QtCore import QObject, Signal
5
+ from qtpy import QtGui, QtWidgets
6
+ from qtpy.QtWidgets import QMessageBox, QDialogButtonBox, QDialog
7
+
8
+
9
+ from pymodaq.utils.config import get_set_remote_path
10
+
11
+ from pymodaq_utils.logger import set_logger, get_module_name
12
+ from pymodaq_gui.parameter import ioxml
13
+ from pymodaq_gui.utils import select_file
14
+ from pymodaq_gui.parameter import ParameterTree, Parameter
15
+ from pymodaq_gui.parameter.pymodaq_ptypes import registerParameterType, GroupParameter
16
+
17
+ logger = set_logger(get_module_name(__file__))
18
+ remote_path = get_set_remote_path()
19
+ remote_types = ['ShortCut', 'Joystick']
20
+
21
+ actuator_actions = ['move_rel', 'move_rel_p', 'move_rel_m']
22
+ detector_actions = ['snap', 'grab', 'stop']
23
+ remote_types = ['Keyboard', 'Joystick']
24
+
25
+ try:
26
+ import pygame
27
+ is_pygame = True
28
+ except ModuleNotFoundError as e:
29
+ remote_types.pop(remote_types.index('Joystick'))
30
+ logger.warning('Could not load pygame module, no joystick configurable')
31
+ is_pygame = False
32
+
33
+
34
+ class ScalableGroupRemote(GroupParameter):
35
+ """
36
+ """
37
+
38
+ def __init__(self, **opts):
39
+ opts['type'] = 'groupremote'
40
+ opts['addText'] = "Add"
41
+ if 'remote' not in opts:
42
+ opts['remote'] = remote_types[0]
43
+ if 'addList' not in opts:
44
+ opts['addList'] = []
45
+ super().__init__(**opts)
46
+
47
+ def addNew(self, typ):
48
+ """
49
+ Add a child.
50
+ """
51
+ name_prefix = 'action' # or 'det_' but they have same length
52
+ child_indexes = [int(par.name()[len(name_prefix) + 1:]) for par in self.children()]
53
+ if not child_indexes:
54
+ newindex = 0
55
+ else:
56
+ newindex = max(child_indexes) + 1
57
+
58
+ params = [{'title': 'Action:', 'name': 'action', 'type': 'list', 'value': typ, 'limits': self.opts['addList']},
59
+ {'title': 'Remote:', 'name': 'remote_type', 'type': 'list', 'value': 'Keyboard',
60
+ 'limits': remote_types},
61
+ ]
62
+ params.extend([
63
+ {'title': 'Set Shortcut:', 'name': 'set_shortcut', 'type': 'bool_push', 'label': 'Set',
64
+ 'value': False},
65
+ {'title': 'Shortcut:', 'name': 'shortcut', 'type': 'str', 'value': ''},
66
+ {'title': 'Set Joystick ID:', 'name': 'set_joystick', 'type': 'bool_push', 'label': 'Set',
67
+ 'value': False, 'visible': False},
68
+
69
+ {'title': 'Joystick ID:', 'name': 'joystickID', 'type': 'int', 'value': -1, 'visible': False},
70
+ {'title': 'Actionner type:', 'name': 'actionner_type', 'type': 'list', 'limits': ['Axis', 'Button', 'Hat'],
71
+ 'visible': False},
72
+ {'title': 'Actionner ID:', 'name': 'actionnerID', 'type': 'int', 'value': -1, 'visible': False},
73
+ ])
74
+
75
+ # for param in params:
76
+ # if param['type'] == 'itemselect' or param['type'] == 'list':
77
+ # param['show_pb'] = True
78
+
79
+ child = {'title': f'Action {newindex:02d}', 'name': f'{name_prefix}{newindex:02d}', 'type': 'group',
80
+ 'removable': True, 'children': params, 'removable': True, 'renamable': False}
81
+
82
+ self.addChild(child)
83
+
84
+
85
+ registerParameterType('groupremote', ScalableGroupRemote, override=True)
86
+
87
+
88
+ class ScalableGroupModules(GroupParameter):
89
+ """
90
+ """
91
+
92
+ def __init__(self, **opts):
93
+ opts['type'] = 'groupremote'
94
+ opts['addText'] = "Add"
95
+ if 'modtype' not in opts:
96
+ opts['modtype'] = 'Actuator'
97
+ if 'addList' not in opts:
98
+ opts['addList'] = []
99
+ super().__init__(**opts)
100
+
101
+ def addNew(self, typ):
102
+ """
103
+ Add a child.
104
+ """
105
+ name_prefix = 'act_' # or 'det_' but they have same length
106
+ child_indexes = [int(par.name()[len(name_prefix) + 1:]) for par in self.children()]
107
+ if not child_indexes:
108
+ newindex = 0
109
+ else:
110
+ newindex = max(child_indexes) + 1
111
+
112
+ if self.opts['modtype'] == 'Actuator':
113
+ addlist = actuator_actions
114
+ else:
115
+ addlist = detector_actions
116
+
117
+ params = [
118
+ {'title': 'Actions:', 'name': 'actions', 'type': 'groupremote', 'value': typ,
119
+ 'limits': self.opts['addList'], 'addList': addlist},
120
+ ]
121
+
122
+ # for param in params:
123
+ # if param['type'] == 'itemselect' or param['type'] == 'list':
124
+ # param['show_pb'] = True
125
+
126
+ if self.opts['modtype'] == 'Actuator':
127
+ child = {'title': f'Actuator {typ}', 'name': f'{name_prefix}{newindex:03d}',
128
+ 'type': 'group',
129
+ 'removable': True, 'children': params, 'removable': True, 'renamable': False}
130
+ else:
131
+ child = {'title': f'Detector {typ}', 'name': f'det_{newindex:03d}', 'type': 'group',
132
+ 'removable': True, 'children': params, 'removable': True, 'renamable': False}
133
+
134
+ if child['name'] not in [child.name() for child in self.children()]:
135
+ self.addChild(child)
136
+
137
+
138
+ registerParameterType('groupmodules', ScalableGroupModules, override=True)
139
+
140
+
141
+ class ShortcutSelection(QtWidgets.QDialog):
142
+ def __init__(self):
143
+ super().__init__()
144
+ layout = QtWidgets.QVBoxLayout()
145
+ self.setLayout(layout)
146
+
147
+ horwidget = QtWidgets.QWidget()
148
+ layout.addWidget(horwidget)
149
+ hor_layout = QtWidgets.QHBoxLayout()
150
+ horwidget.setLayout(hor_layout)
151
+ label = QtWidgets.QLabel('Pressed key on the keyboard:')
152
+ self.label = QtWidgets.QLabel('')
153
+
154
+ hor_layout.addWidget(label)
155
+ hor_layout.addWidget(self.label)
156
+
157
+ buttonBox = QDialogButtonBox()
158
+ buttonBox.addButton(QDialogButtonBox.StandardButton.Ok)
159
+ buttonBox.addButton(QDialogButtonBox.StandardButton.Cancel)
160
+ layout.addWidget(self.label)
161
+ layout.addWidget(buttonBox)
162
+
163
+ buttonBox.accepted.connect(self.accept)
164
+ buttonBox.rejected.connect(self.reject)
165
+
166
+ def keyPressEvent(self, event):
167
+ keyseq = QtGui.QKeySequence(event.key())
168
+ self.label.setText(keyseq.toString())
169
+
170
+
171
+ class JoystickButtonsSelection(QtWidgets.QDialog):
172
+ def __init__(self):
173
+ super().__init__()
174
+ self.setupUI()
175
+
176
+ self.selection = None
177
+
178
+ pygame.init()
179
+ pygame.joystick.init()
180
+ # width, height = 64 * 10, 64 * 8
181
+ # self.screen = pygame.display.set_mode((width, height))
182
+ joystick_count = pygame.joystick.get_count()
183
+ self.joysticks = []
184
+ for ind in range(joystick_count):
185
+ self.joysticks.append(pygame.joystick.Joystick(ind))
186
+ self.joysticks[-1].init()
187
+ self.startTimer(10)
188
+
189
+ def timerEvent(self, event):
190
+ for event in pygame.event.get(): # User did something.
191
+ if 'joy' in event.dict:
192
+ self.settings.child(('joystickID')).setValue(event.joy)
193
+ self.selection = dict(joy=event.joy)
194
+ if event.type == pygame.QUIT: # If user clicked close.
195
+ self.reject()
196
+ elif event.type == pygame.JOYBUTTONDOWN or event.type == pygame.JOYBUTTONUP:
197
+ self.settings.child(('buttonID')).show(True)
198
+ self.settings.child(('axisID')).show(False)
199
+ self.settings.child(('hatID')).show(False)
200
+ self.settings.child(('axis_value')).show(False)
201
+ self.settings.child(('hat_value1')).show(False)
202
+ self.settings.child(('hat_value2')).show(False)
203
+ self.settings.child(('buttonID')).setValue(event.button)
204
+ self.selection.update(dict(button=event.button))
205
+ elif event.type == pygame.JOYAXISMOTION:
206
+ self.settings.child(('buttonID')).show(False)
207
+ self.settings.child(('axisID')).show(True)
208
+ self.settings.child(('hatID')).show(False)
209
+ self.settings.child(('axis_value')).show(True)
210
+ self.settings.child(('axisID')).setValue(event.axis)
211
+ self.settings.child(('axis_value')).setValue(event.value)
212
+ self.settings.child(('hat_value1')).show(False)
213
+ self.settings.child(('hat_value2')).show(False)
214
+ self.selection.update(dict(axis=event.axis, value=event.value))
215
+ elif event.type == pygame.JOYHATMOTION:
216
+ self.settings.child(('buttonID')).show(False)
217
+ self.settings.child(('axisID')).show(False)
218
+ self.settings.child(('hatID')).show(True)
219
+ self.settings.child(('axis_value')).show(True)
220
+ self.settings.child(('hat_value1')).show(True)
221
+ self.settings.child(('hat_value2')).show(True)
222
+ self.settings.child(('hat_value1')).setValue(event.value[0])
223
+ self.settings.child(('hat_value2')).setValue(event.value[1])
224
+ self.selection.update(dict(hat=event.hat, value=event.value))
225
+
226
+ def setupUI(self):
227
+ layout = QtWidgets.QVBoxLayout()
228
+ self.setLayout(layout)
229
+ label = QtWidgets.QLabel('Press a button or move an axis on the Joystick:')
230
+ layout.addWidget(label)
231
+
232
+ params = [{'title': 'Joystick ID', 'name': 'joystickID', 'type': 'int', 'value': -1},
233
+ {'title': 'Button ID', 'name': 'buttonID', 'type': 'int', 'value': -1, 'visible': False},
234
+ {'title': 'Axis ID', 'name': 'axisID', 'type': 'int', 'value': -1, 'visible': False},
235
+ {'title': 'Value:', 'name': 'axis_value', 'type': 'float', 'value': 0., 'visible': False},
236
+ {'title': 'Hat ID', 'name': 'hatID', 'type': 'int', 'value': -1, 'visible': False},
237
+ {'title': 'Value x:', 'name': 'hat_value1', 'type': 'int', 'value': 0, 'visible': False},
238
+ {'title': 'Value y:', 'name': 'hat_value2', 'type': 'int', 'value': 0, 'visible': False}, ]
239
+
240
+ self.settings = Parameter.create(name='settings', type='group', children=params)
241
+ self.settings_tree = ParameterTree()
242
+ # tree.setMinimumWidth(400)
243
+ # self.settings_tree.setMinimumHeight(500)
244
+ self.settings_tree.setParameters(self.settings, showTop=False)
245
+
246
+ layout.addWidget(self.settings_tree)
247
+
248
+ buttonBox = QDialogButtonBox()
249
+ buttonBox.addButton(QDialogButtonBox.StandardButton.Ok)
250
+ buttonBox.addButton(QDialogButtonBox.StandardButton.Cancel)
251
+ layout.addWidget(buttonBox)
252
+
253
+ buttonBox.accepted.connect(self.accept)
254
+ buttonBox.rejected.connect(self.reject)
255
+
256
+
257
+ class RemoteManager(QObject):
258
+ remote_changed = Signal(dict)
259
+
260
+ def __init__(self, actuators=[], detectors=[], msgbox=False):
261
+ super().__init__()
262
+ self.actuators = actuators
263
+ self.detectors = detectors
264
+ if msgbox:
265
+ msgBox = QMessageBox()
266
+ msgBox.setText("Preset Manager?")
267
+ msgBox.setInformativeText("What do you want to do?")
268
+ cancel_button = msgBox.addButton(QMessageBox.StandardButton.Cancel)
269
+ new_button = msgBox.addButton(
270
+ "New", QMessageBox.ButtonRole.ActionRole
271
+ )
272
+ modify_button = msgBox.addButton(
273
+ "Modify", QMessageBox.ButtonRole.AcceptRole
274
+ )
275
+ msgBox.setDefaultButton(QMessageBox.StandardButton.Cancel)
276
+ ret = msgBox.exec()
277
+
278
+ if msgBox.clickedButton() == new_button:
279
+ self.set_new_remote()
280
+
281
+ elif msgBox.clickedButton() == modify_button:
282
+ path = select_file(start_path=remote_path, save=False, ext='xml')
283
+ if path != '':
284
+ self.set_file_remote(str(path))
285
+ else: # cancel
286
+ pass
287
+ params = [{'title': 'Activate all', 'name': 'activate_all', 'type': 'action'},
288
+ {'title': 'Deactivate all', 'name': 'deactivate_all', 'type': 'action'},
289
+ {'title:': 'Actions', 'name': 'action_group', 'type': 'group'}]
290
+
291
+ self.remote_actions = dict(shortcuts=dict([]), joysticks=dict([]))
292
+ self.remote_settings = Parameter.create(title='Remote Settings', name='remote', type='group',
293
+ children=params)
294
+ self.remote_settings.sigTreeStateChanged.connect(self.remote_settings_changed)
295
+ self.remote_settings_tree = ParameterTree()
296
+ self.remote_settings_tree.setParameters(self.remote_settings, showTop=False)
297
+ self.remote_settings.child(('activate_all')).sigActivated.connect(lambda: self.activate_all(True))
298
+ self.remote_settings.child(('deactivate_all')).sigActivated.connect(lambda: self.activate_all(False))
299
+
300
+ def activate_all(self, activate=True):
301
+ for child in self.remote_settings.child(('action_group')).children():
302
+ child.setValue(activate)
303
+
304
+ def set_remote_configuration(self):
305
+ # remove existing shorcuts
306
+ while len(self.remote_actions['shortcuts']):
307
+ self.remote_actions['shortcuts'].pop(list(self.remote_actions['shortcuts'].keys())[0])
308
+
309
+ while len(self.remote_actions['joysticks']):
310
+ self.remote_actions['joysticks'].pop(list(self.remote_actions['joysticks'].keys())[0])
311
+ all_actions = []
312
+ for child in self.remote_params.child('act_actions').children():
313
+ module_name = child.opts['title'].split('Actuator ')[1]
314
+ module_type = 'act'
315
+ for action in child.child(('actions')).children():
316
+ all_actions.append((module_name, action, module_type))
317
+ for child in self.remote_params.child('det_actions').children():
318
+ module_name = child.opts['title'].split('Detector ')[1]
319
+ module_type = 'det'
320
+ for action in child.child(('actions')).children():
321
+ all_actions.append((module_name, action, module_type))
322
+
323
+ for ind, action_tuple in enumerate(all_actions):
324
+ module, action, module_type = action_tuple
325
+ if action.child('remote_type').value() == 'Keyboard':
326
+ # stc = QtWidgets.QShortcut(QtGui.QKeySequence(action.child(('shortcut')).value()), self.dockarea)
327
+ self.remote_settings.child(('action_group')).addChild(
328
+ {'title': f"{module}: {action.child(('action')).value()} "
329
+ f"{action.child(('shortcut')).value()}:",
330
+ 'name': f'shortcut{ind:02d}', 'type': 'led_push', 'value': False})
331
+ self.remote_actions['shortcuts'][f'shortcut{ind:02d}'] = \
332
+ dict(shortcut=action.child(('shortcut')).value(), activated=False, name=f'shortcut{ind:02d}',
333
+ action=action.child(('action')).value(), module_name=module, module_type=module_type)
334
+ else:
335
+ self.remote_settings.child(('action_group')).addChild(
336
+ {'title': f"{module}: {action.child(('action')).value()}=>"
337
+ f"J{action.child(('joystickID')).value()}/"
338
+ f"{action.child(('actionner_type')).value()}"
339
+ f"{action.child(('actionnerID')).value()}:",
340
+ 'name': f'joy{ind:02d}', 'type': 'led_push', 'value': False})
341
+ self.remote_actions['joysticks'][f'joy{ind:02d}'] = \
342
+ dict(joystickID=action.child(('joystickID')).value(),
343
+ actionner_type=action.child(('actionner_type')).value(),
344
+ actionnerID=action.child(('actionnerID')).value(),
345
+ activated=False, name=f'joy{ind:02d}',
346
+ action=action.child(('action')).value(),
347
+ module_name=module, module_type=module_type)
348
+
349
+ self.activate_all()
350
+
351
+ def set_new_remote(self, file=None):
352
+ if file is None:
353
+ file = 'remote_default'
354
+ param = [
355
+ {'title': 'Filename:', 'name': 'filename', 'type': 'str', 'value': file},
356
+ ]
357
+ params_action = [{'title': 'Actuator Actions:', 'name': 'act_actions', 'type': 'groupmodules',
358
+ 'addList': self.actuators, 'modtype': 'Actuator'},
359
+ {'title': 'Detector Actions:', 'name': 'det_actions', 'type': 'groupmodules',
360
+ 'addList': self.detectors, 'modtype': 'Detector'}
361
+ ] # PresetScalableGroupMove(name="Moves")]
362
+ self.remote_params = Parameter.create(title='Preset', name='Preset', type='group',
363
+ children=param + params_action)
364
+ self.remote_params.sigTreeStateChanged.connect(self.parameter_tree_changed)
365
+ logger.info('Creating a new remote file')
366
+ self.show_remote()
367
+
368
+ def parameter_tree_changed(self, param, changes):
369
+ """
370
+ Check for changes in the given (parameter,change,information) tuple list.
371
+ In case of value changed, update the DAQscan_settings tree consequently.
372
+
373
+ =============== ============================================ ==============================
374
+ **Parameters** **Type** **Description**
375
+ *param* instance of pyqtgraph parameter the parameter to be checked
376
+ *changes* (parameter,change,information) tuple list the current changes state
377
+ =============== ============================================ ==============================
378
+ """
379
+ for param, change, data in changes:
380
+ path = self.remote_params.childPath(param)
381
+ if change == 'childAdded':
382
+ pass
383
+
384
+ elif change == 'value':
385
+ if param.name() == 'remote_type':
386
+ status = data == 'Keyboard'
387
+ param.parent().child(('set_shortcut')).show(status)
388
+ param.parent().child(('shortcut')).show(status)
389
+ param.parent().child(('set_joystick')).show(not status)
390
+ param.parent().child(('joystickID')).show(not status)
391
+ param.parent().child(('actionner_type')).show(not status)
392
+ param.parent().child(('actionnerID')).show(not status)
393
+
394
+ elif param.name() == 'set_shortcut':
395
+ msgBox = ShortcutSelection()
396
+ ret = msgBox.exec()
397
+ if ret:
398
+ param.parent().child(('shortcut')).setValue(msgBox.label.text())
399
+ elif param.name() == 'set_joystick':
400
+ msgBox = JoystickButtonsSelection()
401
+ ret = msgBox.exec()
402
+ if ret:
403
+ param.parent().child(('joystickID')).setValue(msgBox.selection['joy'])
404
+ """
405
+ possible cases: ['Axis', 'Button', 'Hat']
406
+ """
407
+ if 'axis' in msgBox.selection:
408
+ param.parent().child(('actionner_type')).setValue('Axis')
409
+ param.parent().child(('actionnerID')).setValue(msgBox.selection['axis'])
410
+ elif 'button' in msgBox.selection:
411
+ param.parent().child(('actionner_type')).setValue('Button')
412
+ param.parent().child(('actionnerID')).setValue(msgBox.selection['button'])
413
+ elif 'hat' in msgBox.selection:
414
+ param.parent().child(('actionner_type')).setValue('Hat')
415
+ param.parent().child(('actionnerID')).setValue(msgBox.selection['hat'])
416
+
417
+ elif change == 'parent':
418
+ pass
419
+
420
+ def remote_settings_changed(self, param, changes):
421
+ for param, change, data in changes:
422
+ path = self.remote_params.childPath(param)
423
+ if change == 'childAdded':
424
+ pass
425
+
426
+ elif change == 'value':
427
+ if 'shortcut' in param.name():
428
+ self.remote_actions['shortcuts'][param.name()]['activated'] = data
429
+ self.remote_changed.emit(dict(action_type='shortcut',
430
+ action_name=param.name(),
431
+ action_dict=self.remote_actions['shortcuts'][param.name()]))
432
+ elif 'joy' in param.name():
433
+ self.remote_actions['joysticks'][param.name()]['activated'] = data
434
+ self.remote_changed.emit(dict(action_type='joystick',
435
+ action_name=param.name(),
436
+ action_dict=self.remote_actions['joysticks'][param.name()]))
437
+
438
+ def set_file_remote(self, filename, show=True):
439
+ """
440
+
441
+ """
442
+ children = ioxml.XML_file_to_parameter(filename)
443
+ self.remote_params = Parameter.create(title='Shortcuts:', name='shortcuts', type='group', children=children)
444
+ if show:
445
+ self.show_remote()
446
+
447
+ def show_remote(self):
448
+ """
449
+
450
+ """
451
+ dialog = QDialog()
452
+ vlayout = QtWidgets.QVBoxLayout()
453
+ tree = ParameterTree()
454
+ # tree.setMinimumWidth(400)
455
+ tree.setMinimumHeight(500)
456
+ tree.setParameters(self.remote_params, showTop=False)
457
+
458
+ vlayout.addWidget(tree)
459
+ dialog.setLayout(vlayout)
460
+ buttonBox = QDialogButtonBox(parent=dialog)
461
+
462
+ buttonBox.addButton("Save", QDialogButtonBox.ButtonRole.AcceptRole)
463
+ buttonBox.accepted.connect(dialog.accept)
464
+ buttonBox.addButton("Cancel", QDialogButtonBox.ButtonRole.RejectRole)
465
+ buttonBox.rejected.connect(dialog.reject)
466
+
467
+ vlayout.addWidget(buttonBox)
468
+ dialog.setWindowTitle('Fill in information about the actions and their shortcuts')
469
+ res = dialog.exec()
470
+
471
+ if res == QDialog.DialogCode.Accepted:
472
+ # save preset parameters in a xml file
473
+ ioxml.parameter_to_xml_file(
474
+ self.remote_params, os.path.join(remote_path, self.remote_params.child('filename').value()))
475
+
476
+
477
+ if __name__ == '__main__':
478
+ actuators = ['act0', 'act1', 'act2']
479
+ detectors = ['det0', 'det1', 'det2']
480
+ app = QtWidgets.QApplication(sys.argv)
481
+ #prog = RemoteManager(actuators=actuators, detectors=detectors, msgbox=True)
482
+ msgBox = JoystickButtonsSelection()
483
+ ret = msgBox.exec()
484
+ sys.exit(app.exec_())
@@ -0,0 +1,6 @@
1
+ from pymodaq_utils.math_utils import *
2
+
3
+ from pymodaq_utils.warnings import deprecation_msg
4
+
5
+ deprecation_msg('Importing math_utils stuff from pymodaq is deprecated in pymodaq>5.0.0,'
6
+ 'please use the pymodaq_utils.math_utils module')
@@ -0,0 +1,6 @@
1
+ from pymodaq_utils.warnings import deprecation_msg
2
+
3
+ from pymodaq_gui.messenger import messagebox
4
+
5
+ deprecation_msg('importing messagebox from pymodaq directly is deprecated. It should now be'
6
+ ' imported from pymodaq_gui.messenger')
@@ -0,0 +1,10 @@
1
+ from pymodaq_gui.parameter import Parameter, ParameterTree, utils, ioxml, pymodaq_ptypes
2
+ from sys import modules as sysmodules
3
+ from pymodaq_utils.warnings import deprecation_msg
4
+
5
+
6
+ sysmodules["pymodaq.utils.parameter.pymodaq_ptypes"] = pymodaq_ptypes
7
+
8
+
9
+ deprecation_msg('Importing Parameter stuff from pymodaq is deprecated in pymodaq>5.0.0,'
10
+ 'please use the pymodaq_gui package')
@@ -0,0 +1,6 @@
1
+ from pymodaq_gui.parameter.utils import *
2
+
3
+ from pymodaq_utils.warnings import deprecation_msg
4
+
5
+ deprecation_msg('Importing Parameter stuff from pymodaq is deprecated in pymodaq>5.0.0,'
6
+ 'please use the pymodaq_gui.parameter module')
@@ -0,0 +1,5 @@
1
+ from importlib import import_module
2
+ from pathlib import Path
3
+
4
+
5
+ from .scanner import Scanner # import this one after the scanners because they have to first be registered
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created the 19/11/2023
4
+
5
+ @author: Sebastien Weber
6
+ """
7
+
8
+ from pathlib import Path
9
+ from pymodaq_utils.config import BaseConfig
10
+
11
+
12
+ class ScanConfig(BaseConfig):
13
+ """Main class to deal with configuration values for this plugin"""
14
+ config_template_path = None
15
+ config_name = f"scanner_settings"
16
+