pymodaq 5.0.0__py3-none-any.whl → 5.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.

Files changed (60) hide show
  1. pymodaq/__init__.py +55 -89
  2. pymodaq/control_modules/daq_move.py +123 -52
  3. pymodaq/control_modules/daq_move_ui.py +42 -11
  4. pymodaq/control_modules/daq_viewer.py +30 -13
  5. pymodaq/control_modules/move_utility_classes.py +345 -78
  6. pymodaq/control_modules/utils.py +26 -9
  7. pymodaq/control_modules/viewer_utility_classes.py +51 -14
  8. pymodaq/daq_utils/daq_utils.py +6 -0
  9. pymodaq/dashboard.py +532 -263
  10. pymodaq/examples/qt_less_standalone_module.py +128 -0
  11. pymodaq/extensions/bayesian/bayesian_optimisation.py +30 -21
  12. pymodaq/extensions/bayesian/utils.py +6 -3
  13. pymodaq/extensions/daq_logger/__init__.py +1 -0
  14. pymodaq/extensions/daq_logger/daq_logger.py +4 -5
  15. pymodaq/extensions/daq_scan.py +1 -3
  16. pymodaq/extensions/daq_scan_ui.py +7 -9
  17. pymodaq/extensions/pid/__init__.py +0 -1
  18. pymodaq/extensions/pid/actuator_controller.py +13 -0
  19. pymodaq/extensions/pid/daq_move_PID.py +25 -46
  20. pymodaq/extensions/pid/pid_controller.py +48 -40
  21. pymodaq/extensions/pid/utils.py +3 -2
  22. pymodaq/extensions/utils.py +41 -7
  23. pymodaq/resources/setup_plugin.py +1 -0
  24. pymodaq/updater.py +107 -0
  25. pymodaq/utils/chrono_timer.py +6 -7
  26. pymodaq/utils/daq_utils.py +6 -3
  27. pymodaq/utils/data.py +11 -16
  28. pymodaq/utils/enums.py +6 -0
  29. pymodaq/utils/gui_utils/loader_utils.py +27 -2
  30. pymodaq/utils/gui_utils/utils.py +9 -12
  31. pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
  32. pymodaq/utils/leco/daq_move_LECODirector.py +21 -14
  33. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +13 -8
  34. pymodaq/utils/leco/pymodaq_listener.py +8 -7
  35. pymodaq/utils/leco/utils.py +33 -7
  36. pymodaq/utils/managers/modules_manager.py +20 -10
  37. pymodaq/utils/managers/overshoot_manager.py +45 -1
  38. pymodaq/utils/managers/preset_manager.py +22 -46
  39. pymodaq/utils/managers/preset_manager_utils.py +17 -13
  40. pymodaq/utils/managers/remote_manager.py +1 -1
  41. pymodaq/utils/messenger.py +6 -0
  42. pymodaq/utils/parameter/__init__.py +5 -1
  43. pymodaq/utils/tcp_ip/mysocket.py +4 -110
  44. pymodaq/utils/tcp_ip/serializer.py +4 -769
  45. pymodaq/utils/tcp_ip/tcp_server_client.py +5 -5
  46. pymodaq-5.0.1.dist-info/METADATA +242 -0
  47. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/RECORD +51 -52
  48. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/WHEEL +1 -1
  49. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/entry_points.txt +1 -0
  50. pymodaq/examples/custom_app.py +0 -255
  51. pymodaq/examples/custom_viewer.py +0 -112
  52. pymodaq/examples/parameter_ex.py +0 -158
  53. pymodaq/examples/preset_MockCamera.xml +0 -1
  54. pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py +0 -142
  55. pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui +0 -232
  56. pymodaq/post_treatment/daq_measurement/daq_measurement_main.py +0 -391
  57. pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -2
  58. pymodaq-5.0.0.dist-info/METADATA +0 -166
  59. /pymodaq/{post_treatment/daq_measurement → daq_utils}/__init__.py +0 -0
  60. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -7,6 +7,7 @@ Created the 28/07/2022
7
7
 
8
8
  from typing import List
9
9
  import sys
10
+ from pint.errors import DimensionalityError
10
11
 
11
12
  from qtpy import QtWidgets
12
13
  from qtpy.QtCore import Signal, Qt
@@ -14,7 +15,10 @@ from qtpy.QtWidgets import QHBoxLayout, QVBoxLayout, QGridLayout, QWidget, QTool
14
15
 
15
16
  from pymodaq_utils.utils import ThreadCommand
16
17
  from pymodaq_utils.config import Config
17
- from pymodaq_gui.utils.widgets import PushButtonIcon, LabelWithFont, SpinBox, QSpinBox_ro, QLED
18
+
19
+ from pymodaq_data import Q_
20
+
21
+ from pymodaq_gui.utils.widgets import PushButtonIcon, LabelWithFont, SpinBox, QSpinBox_ro, QLED, QSpinBoxWithShortcut
18
22
  from pymodaq_gui.utils import DockArea
19
23
  from pymodaq_gui.plotting.data_viewers.viewer import ViewerDispatcher
20
24
 
@@ -65,12 +69,17 @@ class DAQ_Move_UI(ControlModuleUI):
65
69
 
66
70
  super().__init__(parent)
67
71
  self.title = title
72
+ self._unit = ''
68
73
  self.setup_ui()
69
74
 
70
75
  self.enable_move_buttons(False)
71
76
 
72
77
  def display_value(self, value: DataActuator):
73
- self.current_value_sb.setValue(value.value())
78
+ try:
79
+ self.current_value_sb.setValue(value.value(self._unit))
80
+ except DimensionalityError as e:
81
+ value.force_units(self._unit)
82
+ self.current_value_sb.setValue(value.value())
74
83
 
75
84
  @property
76
85
  def actuator_init(self):
@@ -193,9 +202,9 @@ class DAQ_Move_UI(ControlModuleUI):
193
202
  self.main_ui.layout().addWidget(self.toolbar, 0, 0, 1, 2)
194
203
  self.main_ui.layout().addWidget(self.move_toolbar, 1, 0, 1, 2)
195
204
 
196
- self.abs_value_sb = SpinBox(step=0.1, dec=True)
205
+ self.abs_value_sb = QSpinBoxWithShortcut(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'))
197
206
  self.abs_value_sb.setStyleSheet("background-color : lightgreen; color: black")
198
- self.abs_value_sb_2 = SpinBox(step=0.1, dec=True)
207
+ self.abs_value_sb_2 = QSpinBoxWithShortcut(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'))
199
208
  self.abs_value_sb_2.setStyleSheet("background-color : lightcoral; color: black")
200
209
  self.move_toolbar.addWidget(self.abs_value_sb)
201
210
  self.move_toolbar.addWidget(self.abs_value_sb_2)
@@ -221,7 +230,7 @@ class DAQ_Move_UI(ControlModuleUI):
221
230
  self.control_ui.layout().addWidget(LabelWithFont('Abs. Value'), 0, 0)
222
231
  self.find_home_pb = PushButtonIcon('home2', 'Find Home')
223
232
  self.control_ui.layout().addWidget(self.find_home_pb, 0, 1)
224
- self.abs_value_sb_bis = SpinBox(step=0.1, dec=True)
233
+ self.abs_value_sb_bis = QSpinBoxWithShortcut(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'))
225
234
  self.control_ui.layout().addWidget(self.abs_value_sb_bis, 1, 0)
226
235
  self.move_abs_pb = PushButtonIcon('Move', 'Set Abs.',
227
236
  tip='Set the value of the actuator to the set absolute value')
@@ -230,7 +239,8 @@ class DAQ_Move_UI(ControlModuleUI):
230
239
  self.move_rel_plus_pb = PushButtonIcon('MoveUp', 'Set Rel. (+)')
231
240
  self.control_ui.layout().addWidget(self.move_rel_plus_pb, 2, 1)
232
241
 
233
- self.rel_value_sb = SpinBox(step=0.1, dec=True)
242
+ self.rel_value_sb = QSpinBoxWithShortcut(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'),
243
+ key_sequences=("Ctrl+E","Ctrl+Shift+E"),)
234
244
  self.control_ui.layout().addWidget(self.rel_value_sb, 3, 0)
235
245
  self.move_rel_minus_pb = PushButtonIcon('MoveDown', 'Set Rel. (-)')
236
246
  self.control_ui.layout().addWidget(self.move_rel_minus_pb, 3, 1)
@@ -250,8 +260,21 @@ class DAQ_Move_UI(ControlModuleUI):
250
260
  self.statusbar.setMaximumHeight(30)
251
261
  self.parent.layout().addWidget(self.statusbar)
252
262
 
263
+ def set_abs_value_red(self, value: Q_):
264
+ self.abs_value_sb_2.setValue(value.m_as(self._unit))
265
+
266
+ def set_abs_value_green(self, value: Q_):
267
+ self.abs_value_sb.setValue(value.m_as(self._unit))
268
+
269
+ def set_abs_value(self, value: Q_):
270
+ self.abs_value_sb_bis.setValue(value.m_as(self._unit))
271
+
272
+ def set_rel_value(self, value: Q_):
273
+ self.rel_value_sb.setValue(value.m_as(self._unit))
274
+
253
275
  def set_unit_as_suffix(self, unit: str):
254
276
  """Will append the actuator units in the value display"""
277
+ self._unit = unit
255
278
  self.current_value_sb.setOpts(suffix=unit)
256
279
  self.abs_value_sb_bis.setOpts(suffix=unit)
257
280
  self.abs_value_sb.setOpts(suffix=unit)
@@ -295,11 +318,17 @@ class DAQ_Move_UI(ControlModuleUI):
295
318
  self.connect_action('show_config', lambda: self.command_sig.emit(ThreadCommand('show_config', )))
296
319
 
297
320
  self.move_abs_pb.clicked.connect(lambda: self.emit_move_abs(self.abs_value_sb_bis))
321
+ self.abs_value_sb.shortcut["Ctrl+E"].activated.connect(lambda: self.emit_move_abs(self.abs_value_sb))
322
+ self.abs_value_sb_2.shortcut["Ctrl+E"].activated.connect(lambda: self.emit_move_abs(self.abs_value_sb_2))
323
+ self.abs_value_sb_bis.shortcut["Ctrl+E"].activated.connect(lambda: self.emit_move_abs(self.abs_value_sb_bis))
324
+
298
325
 
299
326
  self.rel_value_sb.valueChanged.connect(lambda: self.command_sig.emit(
300
327
  ThreadCommand('rel_value', self.rel_value_sb.value())))
301
328
  self.move_rel_plus_pb.clicked.connect(lambda: self.emit_move_rel('+'))
302
329
  self.move_rel_minus_pb.clicked.connect(lambda: self.emit_move_rel('-'))
330
+ self.rel_value_sb.shortcut["Ctrl+E"].activated.connect(lambda: self.emit_move_rel('+'))
331
+ self.rel_value_sb.shortcut["Ctrl+Shift+E"].activated.connect(lambda: self.emit_move_rel('-'))
303
332
 
304
333
  self.find_home_pb.clicked.connect(lambda: self.command_sig.emit(ThreadCommand('find_home', )))
305
334
  self.stop_pb.clicked.connect(lambda: self.command_sig.emit(ThreadCommand('stop', )))
@@ -328,12 +357,14 @@ class DAQ_Move_UI(ControlModuleUI):
328
357
 
329
358
  def emit_move_abs(self, spinbox):
330
359
  spinbox.editingFinished.emit()
331
- self.command_sig.emit(ThreadCommand('move_abs', DataActuator(data=spinbox.value())))
360
+ self.command_sig.emit(ThreadCommand('move_abs', DataActuator(data=spinbox.value(),
361
+ units=self._unit)))
332
362
 
333
363
  def emit_move_rel(self, sign):
334
- self.command_sig.emit(ThreadCommand('move_rel',
335
- DataActuator(data=self.rel_value_sb.value() * (1 if sign == '+'
336
- else -1))))
364
+ self.command_sig.emit(ThreadCommand(
365
+ 'move_rel',
366
+ DataActuator(data=self.rel_value_sb.value() * (1 if sign == '+' else -1),
367
+ units=self._unit)))
337
368
 
338
369
  def close(self):
339
370
  self.graph_ui.close()
@@ -341,7 +372,7 @@ class DAQ_Move_UI(ControlModuleUI):
341
372
 
342
373
 
343
374
  def main(init_qt=True):
344
- from pymodaq.utils.gui_utils.dock import DockArea
375
+ from pymodaq_gui.utils.dock import DockArea
345
376
  if init_qt: # used for the test suite
346
377
  app = QtWidgets.QApplication(sys.argv)
347
378
 
@@ -43,6 +43,7 @@ from pymodaq.control_modules.viewer_utility_classes import params as daq_viewer_
43
43
  from pymodaq_utils import utils
44
44
  from pymodaq_utils.warnings import deprecation_msg
45
45
  from pymodaq_gui.utils import DockArea, Dock
46
+ from pymodaq_gui.utils.utils import mkQApp
46
47
 
47
48
  from pymodaq.utils.gui_utils import get_splash_sc
48
49
  from pymodaq.control_modules.daq_viewer_ui import DAQ_Viewer_UI
@@ -269,6 +270,20 @@ class DAQ_Viewer(ParameterControlModule):
269
270
  deprecation_msg('viewers_docks is a deprecated property use viewer_docks instead')
270
271
  return self.viewer_docks
271
272
 
273
+ @property
274
+ def master(self) -> bool:
275
+ """ Get/Set programmatically the Master/Slave status of a detector"""
276
+ if self.initialized_state:
277
+ return self.settings['detector_settings', 'controller_status'] == 'Master'
278
+ else:
279
+ return True
280
+
281
+ @master.setter
282
+ def master(self, is_master: bool):
283
+ if self.initialized_state:
284
+ self.settings.child('detector_settings', 'controller_status').setValue(
285
+ 'Master' if is_master else 'Slave')
286
+
272
287
  def daq_type_changed_from_ui(self, daq_type: DAQTypesEnum):
273
288
  """ Apply changes from the selection of a different DAQTypesEnum in the UI
274
289
 
@@ -376,7 +391,7 @@ class DAQ_Viewer(ParameterControlModule):
376
391
  return self._viewers
377
392
 
378
393
  @viewers.setter
379
- def viewers(self, viewers):
394
+ def viewers(self, viewers: List[ViewerBase]):
380
395
  for viewer in self._viewers:
381
396
  try:
382
397
  viewer.data_to_export_signal.disconnect()
@@ -392,6 +407,11 @@ class DAQ_Viewer(ParameterControlModule):
392
407
  lambda roi_info: self.command_hardware.emit(
393
408
  ThreadCommand('roi_select',
394
409
  dict(roi_info=roi_info, ind_viewer=ind_viewer))))
410
+ viewer.crosshair_dragged.connect(
411
+ lambda crosshair_info: self.command_hardware.emit(
412
+ ThreadCommand('crosshair',
413
+ dict(crosshair_info=crosshair_info, ind_viewer=ind_viewer))))
414
+
395
415
 
396
416
  self._viewers = viewers
397
417
 
@@ -1004,7 +1024,8 @@ class DAQ_Viewer(ParameterControlModule):
1004
1024
  if self.settings.child('main_settings', 'overshoot', 'stop_overshoot').value():
1005
1025
  for dwa in dte:
1006
1026
  for data_array in dwa.data:
1007
- if any(data_array >= self.settings.child('main_settings', 'overshoot', 'overshoot_value').value()):
1027
+ if np.any(data_array >= self.settings['main_settings', 'overshoot',
1028
+ 'overshoot_value']):
1008
1029
  self.overshoot_signal.emit(True)
1009
1030
 
1010
1031
  def get_scaling_options(self):
@@ -1046,11 +1067,11 @@ class DAQ_Viewer(ParameterControlModule):
1046
1067
  super().thread_status(status, 'detector')
1047
1068
 
1048
1069
  if status.command == "ini_detector":
1049
- self.update_status("detector initialized: " + str(status.attribute[0]['initialized']))
1070
+ self.update_status("detector initialized: " + str(status.attribute['initialized']))
1050
1071
  if self.ui is not None:
1051
- self.ui.detector_init = status.attribute[0]['initialized']
1052
- if status.attribute[0]['initialized']:
1053
- self.controller = status.attribute[0]['controller']
1072
+ self.ui.detector_init = status.attribute['initialized']
1073
+ if status.attribute['initialized']:
1074
+ self.controller = status.attribute['controller']
1054
1075
  self._initialized_state = True
1055
1076
  else:
1056
1077
  self._initialized_state = False
@@ -1214,7 +1235,7 @@ class DAQ_Detector(QObject):
1214
1235
  """
1215
1236
  if command.command == "ini_detector":
1216
1237
  status = self.ini_detector(*command.attribute)
1217
- self.status_sig.emit(ThreadCommand(command.command, [status, 'log']))
1238
+ self.status_sig.emit(ThreadCommand(command.command, status))
1218
1239
 
1219
1240
  elif command.command == "close":
1220
1241
  status = self.close()
@@ -1416,7 +1437,7 @@ class DAQ_Detector(QObject):
1416
1437
  def close(self):
1417
1438
  """ Call the close method of the instrument plugin class
1418
1439
  """
1419
- if self.detector is not None:
1440
+ if self.detector is not None and self.detector.controller is not None:
1420
1441
  status = self.detector.close()
1421
1442
  return status
1422
1443
 
@@ -1444,16 +1465,12 @@ def main(init_qt=True, init_det=False):
1444
1465
  """ Method called to start the DAQ_Viewer in standalone mode"""
1445
1466
 
1446
1467
  if init_qt: # used for the test suite
1447
- app = QtWidgets.QApplication(sys.argv)
1448
- if config('style', 'darkstyle'):
1449
- import qdarkstyle
1450
- app.setStyleSheet(qdarkstyle.load_stylesheet(qdarkstyle.DarkPalette))
1468
+ app = mkQApp("PyMoDAQ Viewer")
1451
1469
 
1452
1470
  win = QtWidgets.QMainWindow()
1453
1471
  area = DockArea()
1454
1472
  win.setCentralWidget(area)
1455
1473
  win.resize(1000, 500)
1456
- win.setWindowTitle('PyMoDAQ Viewer')
1457
1474
  win.show()
1458
1475
 
1459
1476
  title = "Testing"