pymodaq 5.0.1__tar.gz → 5.0.3__tar.gz

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 (122) hide show
  1. {pymodaq-5.0.1 → pymodaq-5.0.3}/PKG-INFO +4 -4
  2. {pymodaq-5.0.1 → pymodaq-5.0.3}/pyproject.toml +3 -3
  3. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/daq_move.py +19 -16
  4. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/daq_viewer.py +2 -0
  5. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/move_utility_classes.py +2 -2
  6. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/dashboard.py +4 -4
  7. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_scan.py +71 -15
  8. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/pid/pid_controller.py +1 -1
  9. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/pid/utils.py +4 -29
  10. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/post_treatment/load_and_plot.py +43 -10
  11. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/data.py +11 -2
  12. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/gui_utils/loader_utils.py +2 -0
  13. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/h5modules/module_saving.py +5 -2
  14. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/daq_move_LECODirector.py +1 -2
  15. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/daq_xDviewer_LECODirector.py +2 -1
  16. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/leco_director.py +4 -3
  17. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/pymodaq_listener.py +1 -6
  18. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/utils.py +9 -2
  19. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/managers/modules_manager.py +2 -2
  20. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/tcp_ip/serializer.py +1 -1
  21. {pymodaq-5.0.1 → pymodaq-5.0.3}/.gitignore +0 -0
  22. {pymodaq-5.0.1 → pymodaq-5.0.3}/LICENSE +0 -0
  23. {pymodaq-5.0.1 → pymodaq-5.0.3}/README.rst +0 -0
  24. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/__init__.py +0 -0
  25. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/__init__.py +0 -0
  26. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/daq_move_ui.py +0 -0
  27. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/daq_viewer_ui.py +0 -0
  28. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/mocks.py +0 -0
  29. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/utils.py +0 -0
  30. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/control_modules/viewer_utility_classes.py +0 -0
  31. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/daq_utils/__init__.py +0 -0
  32. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/daq_utils/daq_utils.py +0 -0
  33. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.aliases +0 -0
  34. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvlps +0 -0
  35. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvproj +0 -0
  36. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.vi +0 -0
  37. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_1Dgaussian.vi +0 -0
  38. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_2Dgaussian.vi +0 -0
  39. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_cmd.vi +0 -0
  40. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_float.vi +0 -0
  41. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_int.vi +0 -0
  42. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_data.vi +0 -0
  43. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_int.vi +0 -0
  44. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_scalar.vi +0 -0
  45. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_string.vi +0 -0
  46. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/client_state.ctl +0 -0
  47. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/Labview_TCP_Client/cmd_types.ctl +0 -0
  48. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/__init__.py +0 -0
  49. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/function_plotter.py +0 -0
  50. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/nonlinearscanner.py +0 -0
  51. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/qt_less_standalone_module.py +0 -0
  52. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/examples/tcp_client.py +0 -0
  53. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/__init__.py +0 -0
  54. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/bayesian/__init__.py +0 -0
  55. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -0
  56. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/bayesian/utils.py +0 -0
  57. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/console.py +0 -0
  58. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_logger/__init__.py +0 -0
  59. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_logger/abstract.py +0 -0
  60. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_logger/daq_logger.py +0 -0
  61. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_logger/db/__init__.py +0 -0
  62. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_logger/db/db_logger.py +0 -0
  63. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_logger/db/db_logger_models.py +0 -0
  64. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_logger/h5logging.py +0 -0
  65. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/daq_scan_ui.py +0 -0
  66. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/h5browser.py +0 -0
  67. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/pid/__init__.py +0 -0
  68. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/pid/actuator_controller.py +0 -0
  69. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/pid/daq_move_PID.py +0 -0
  70. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/extensions/utils.py +0 -0
  71. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/icon.ico +0 -0
  72. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/post_treatment/__init__.py +0 -0
  73. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/resources/__init__.py +0 -0
  74. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/resources/preset_default.xml +0 -0
  75. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/resources/setup_plugin.py +0 -0
  76. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/splash.png +0 -0
  77. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/updater.py +0 -0
  78. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/__init__.py +0 -0
  79. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/array_manipulation.py +0 -0
  80. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/calibration_camera.py +0 -0
  81. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/chrono_timer.py +0 -0
  82. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/config.py +0 -0
  83. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/conftests.py +0 -0
  84. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/daq_utils.py +0 -0
  85. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/enums.py +0 -0
  86. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/exceptions.py +0 -0
  87. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/gui_utils/__init__.py +0 -0
  88. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/gui_utils/utils.py +0 -0
  89. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/gui_utils/widgets/lcd.py +0 -0
  90. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/h5modules/__init__.py +0 -0
  91. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/__init__.py +0 -0
  92. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/desktop.ini +0 -0
  93. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/leco/director_utils.py +0 -0
  94. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/logger.py +0 -0
  95. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/managers/__init__.py +0 -0
  96. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/managers/batchscan_manager.py +0 -0
  97. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/managers/overshoot_manager.py +0 -0
  98. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/managers/preset_manager.py +0 -0
  99. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/managers/preset_manager_utils.py +0 -0
  100. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/managers/remote_manager.py +0 -0
  101. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/math_utils.py +0 -0
  102. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/messenger.py +0 -0
  103. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/parameter/__init__.py +0 -0
  104. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/parameter/utils.py +0 -0
  105. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/__init__.py +0 -0
  106. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scan_config.py +0 -0
  107. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scan_factory.py +0 -0
  108. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scan_selector.py +0 -0
  109. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scanner.py +0 -0
  110. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scanners/_1d_scanners.py +0 -0
  111. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scanners/_2d_scanners.py +0 -0
  112. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scanners/__init__.py +0 -0
  113. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scanners/sequential.py +0 -0
  114. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/scanners/tabular.py +0 -0
  115. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/scanner/utils.py +0 -0
  116. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/svg/__init__.py +0 -0
  117. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/svg/svg_renderer.py +0 -0
  118. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/svg/svg_view.py +0 -0
  119. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/svg/svg_viewer2D.py +0 -0
  120. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/tcp_ip/__init__.py +0 -0
  121. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/tcp_ip/mysocket.py +0 -0
  122. {pymodaq-5.0.1 → pymodaq-5.0.3}/src/pymodaq/utils/tcp_ip/tcp_server_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymodaq
3
- Version: 5.0.1
3
+ Version: 5.0.3
4
4
  Summary: Modular Data Acquisition with Python
5
5
  Project-URL: Homepage, http://pymodaq.cnrs.fr
6
6
  Project-URL: Source, https://github.com/PyMoDAQ/PyMoDAQ
@@ -50,11 +50,11 @@ Requires-Dist: numpy<2.0.0
50
50
  Requires-Dist: packaging
51
51
  Requires-Dist: pint
52
52
  Requires-Dist: pyleco>0.3; python_version >= '3.8'
53
- Requires-Dist: pymodaq-data>=5.0.15
54
- Requires-Dist: pymodaq-gui>=5.0.16
53
+ Requires-Dist: pymodaq-data>=5.0.18
54
+ Requires-Dist: pymodaq-gui>=5.0.17
55
55
  Requires-Dist: pymodaq-plugin-manager>=0.0.17
56
56
  Requires-Dist: pymodaq-plugins-mock>=5.0.5
57
- Requires-Dist: pymodaq-utils
57
+ Requires-Dist: pymodaq-utils>=0.0.14
58
58
  Requires-Dist: pyqtgraph>=0.12
59
59
  Requires-Dist: python-dateutil
60
60
  Requires-Dist: qtconsole
@@ -31,9 +31,9 @@ classifiers = [
31
31
  "Topic :: Software Development :: User Interfaces",
32
32
  ]
33
33
  dependencies = [
34
- "pymodaq_utils",
35
- "pymodaq_gui>=5.0.16",
36
- "pymodaq_data>=5.0.15",
34
+ "pymodaq_utils>=0.0.14",
35
+ "pymodaq_gui>=5.0.17",
36
+ "pymodaq_data>=5.0.18",
37
37
  "easydict",
38
38
  "multipledispatch",
39
39
  "numpy < 2.0.0",
@@ -10,7 +10,7 @@ from __future__ import annotations
10
10
  import numbers
11
11
  from importlib import import_module
12
12
  from numbers import Number
13
- from random import randint
13
+
14
14
  import sys
15
15
  from typing import List, Tuple, Union, Optional, Type
16
16
  import numpy as np
@@ -472,16 +472,7 @@ class DAQ_Move(ParameterControlModule):
472
472
  self.init_signal.emit(self._initialized_state)
473
473
 
474
474
  elif status.command == "get_actuator_value" or status.command == 'check_position':
475
- if isinstance(status.attribute, DataActuator):
476
- data_act: DataActuator = status.attribute
477
- else:
478
- data_act: DataActuator = status.attribute[0] # backcompatibility
479
- data_act.name = self.title # for the DataActuator name to be the title of the DAQ_Move
480
- if (not Unit(self.units).is_compatible_with(Unit(data_act.units)) and
481
- data_act.units == ''): #this happens if the units have not been specified in
482
- # the plugin
483
- data_act.force_units(self.units)
484
-
475
+ data_act = self._check_data_type(status.attribute)
485
476
  if self.ui is not None:
486
477
  self.ui.display_value(data_act)
487
478
  if self.ui.is_action_checked('show_graph'):
@@ -495,11 +486,7 @@ class DAQ_Move(ParameterControlModule):
495
486
  self._command_tcpip.emit(ThreadCommand(LECOMoveCommands.POSITION, data_act))
496
487
 
497
488
  elif status.command == "move_done":
498
- if isinstance(status.attribute, DataActuator):
499
- data_act: DataActuator = status.attribute
500
- else:
501
- data_act: DataActuator = status.attribute[0] # deprecated
502
- data_act.name = self.title # for the DataActuator name to be the title of the DAQ_Move
489
+ data_act = self._check_data_type(status.attribute)
503
490
  if self.ui is not None:
504
491
  self.ui.display_value(data_act)
505
492
  self.ui.move_done = True
@@ -524,6 +511,22 @@ class DAQ_Move(ParameterControlModule):
524
511
  elif status.command == 'units':
525
512
  self.units = status.attribute
526
513
 
514
+ def _check_data_type(self, data_act: Union[list[np.ndarray], float, DataActuator]) -> DataActuator:
515
+ """ Make sure the data is a DataActuator
516
+
517
+ Mostly to make sure DAQ_Move is backcompatible with old style plugins
518
+ """
519
+ if isinstance(data_act, list): # backcompatibility
520
+ data_act = data_act[0]
521
+ if isinstance(data_act, np.ndarray): # backcompatibility
522
+ data_act = DataActuator(data=[data_act], units=self.units)
523
+ data_act.name = self.title # for the DataActuator name to be the title of the DAQ_Move
524
+ if (not Unit(self.units).is_compatible_with(Unit(data_act.units)) and
525
+ data_act.units == ''): #this happens if the units have not been specified in
526
+ # the plugin
527
+ data_act.force_units(self.units)
528
+ return data_act
529
+
527
530
  def get_actuator_value(self):
528
531
  """Get the current actuator value via the "get_actuator_value" command send to the hardware
529
532
 
@@ -6,8 +6,10 @@ Created on Wed Jan 10 16:54:14 2018
6
6
  """
7
7
  from __future__ import annotations
8
8
  from importlib import import_module
9
+
9
10
  from collections import OrderedDict
10
11
  import copy
12
+
11
13
  import os
12
14
  from pathlib import Path
13
15
  from random import randint
@@ -536,8 +536,8 @@ class DAQ_Move_base(QObject):
536
536
  return self._current_value
537
537
 
538
538
  @current_value.setter
539
- def current_value(self, value: Union[float, DataActuator]):
540
- if isinstance(value, numbers.Number):
539
+ def current_value(self, value: Union[float, np.ndarray, DataActuator]):
540
+ if isinstance(value, numbers.Number) or isinstance(value, np.ndarray):
541
541
  self._current_value = DataActuator(self._title, data=value,
542
542
  units=self.axis_unit)
543
543
  else:
@@ -45,7 +45,7 @@ from pymodaq.utils import config as config_mod_pymodaq
45
45
 
46
46
  from pymodaq.control_modules.daq_move import DAQ_Move
47
47
  from pymodaq.control_modules.daq_viewer import DAQ_Viewer
48
- from pymodaq.utils.gui_utils import get_splash_sc
48
+ from pymodaq_gui.utils.splash import get_splash_sc
49
49
 
50
50
  from pymodaq import extensions as extmod
51
51
 
@@ -395,11 +395,11 @@ class DashBoard(CustomApp):
395
395
  self.add_action('modify_preset', 'Modify Preset', '',
396
396
  'Modify an existing experimental setup configuration file: a "preset"',
397
397
  auto_toolbar=False)
398
- self.add_action('load_preset', 'LOAD', 'Open',
399
- tip='Load the selected Preset: ')
398
+
400
399
  self.add_widget('preset_list', QtWidgets.QComboBox, toolbar=self.toolbar,
401
400
  signal_str='currentTextChanged', slot=self.update_preset_action)
402
-
401
+ self.add_action('load_preset', 'LOAD', 'Open',
402
+ tip='Load the selected Preset: ')
403
403
  self.update_preset_action_list()
404
404
 
405
405
  self.add_action('new_overshoot', 'New Overshoot', '',
@@ -86,7 +86,12 @@ class DAQScan(QObject, ParameterManager):
86
86
  {'title': 'Timeout (ms)', 'name': 'timeout', 'type': 'int', 'value': 10000},
87
87
  ]},
88
88
  {'title': 'Scan options', 'name': 'scan_options', 'type': 'group', 'children': [
89
- {'title': 'Naverage:', 'name': 'scan_average', 'type': 'int', 'value': 1, 'min': 1},
89
+ {'title': 'Naverage:', 'name': 'scan_average', 'type': 'int',
90
+ 'value': config('scan', 'Naverage'), 'min': 1},
91
+ {'title': 'Plot on top:', 'name': 'average_on_top', 'type': 'bool',
92
+ 'value': config('scan', 'average_on_top'),
93
+ 'tip': 'At the second iteration will plot the averaged scan on top (True) of the current one'
94
+ 'or in a second panel (False)'},
90
95
  ]},
91
96
 
92
97
  {'title': 'Plotting options', 'name': 'plot_options', 'type': 'group', 'children': [
@@ -439,7 +444,7 @@ class DAQScan(QObject, ParameterManager):
439
444
  if not os.path.isdir(self.h5saver.settings['base_path']):
440
445
  os.mkdir(self.h5saver.settings['base_path'])
441
446
  filename = gutils.file_io.select_file(self.h5saver.settings['base_path'], save=True, ext='h5')
442
- self.h5saver.h5_file.copy_file(str(filename))
447
+ self.h5saver.h5_file.copy_file(str(filename), overwrite=True)
443
448
 
444
449
  def save_metadata(self, node, type_info='dataset_info'):
445
450
  """
@@ -597,7 +602,7 @@ class DAQScan(QObject, ParameterManager):
597
602
  for ind, pos in enumerate(positions):
598
603
  dte.append(DataActuator(actuators[ind].title, data=float(pos)))
599
604
 
600
- self.modules_manager.move_actuators(dte)
605
+ self.modules_manager.move_actuators(dte, polling=False)
601
606
 
602
607
  def value_changed(self, param):
603
608
  """
@@ -616,23 +621,52 @@ class DAQScan(QObject, ParameterManager):
616
621
  self.settings.child('plot_options', 'plot_0d').setValue(dict(all_items=[], selected=[]))
617
622
  self.settings.child('plot_options', 'plot_1d').setValue(dict(all_items=[], selected=[]))
618
623
 
619
- def prepare_viewers(self):
624
+ def check_number_type_viewers(self) -> Tuple[
625
+ List[ViewersEnum],
626
+ List[str],
627
+ bool]:
628
+ """ Assert from selected options the number and type of needed viewers for live plotting
620
629
 
621
- viewers_enum = [ViewersEnum('Data0D').increase_dim(self.scanner.n_axes)
630
+ Return
631
+ ------
632
+ List[ViewersEnum]: the list of needed viewers
633
+ List[str]: the list of data names to be plotted in the corresponding viewer
634
+ """
635
+ viewer2D_overload = False
636
+ viewers_enum = [ViewersEnum.Viewer0D.increase_dim(self.scanner.n_axes)
622
637
  for _ in range(len(self.settings['plot_options', 'plot_0d']['selected']))]
623
638
  data_names = self.settings['plot_options', 'plot_0d']['selected'][:]
624
639
 
625
- if self.settings['plot_options', 'group0D'] and len(viewers_enum) > 0 and ViewersEnum('Data1D') in viewers_enum:
626
- viewers_enum = [ViewersEnum('Data1D')]
640
+ if self.settings['plot_options', 'group0D'] and len(viewers_enum) > 0 and ViewersEnum.Viewer1D in viewers_enum:
641
+ viewers_enum = [ViewersEnum.Viewer1D]
627
642
  data_names = [self.live_plotter.grouped_data0D_fullname]
628
- elif self.settings['plot_options', 'group0D'] and len(viewers_enum) > 0 and ViewersEnum('Data2D') in viewers_enum:
629
- viewers_enum = [ViewersEnum('Data2D')]
643
+ elif (self.settings['plot_options', 'group0D'] and len(viewers_enum) > 0 and
644
+ ViewersEnum.Viewer2D in viewers_enum):
645
+ viewers_enum = [ViewersEnum.Viewer2D]
646
+ n2Dplots = len(data_names)
647
+ if (self.settings['scan_options', 'scan_average'] > 1 and
648
+ self.settings['scan_options', 'average_on_top']):
649
+ n2Dplots *= 2
650
+ if n2Dplots > 3:
651
+ viewer2D_overload = True
630
652
  data_names = [self.live_plotter.grouped_data0D_fullname]
631
653
 
632
654
  if self.scanner.n_axes <= 1:
633
- viewers_enum.extend([ViewersEnum('Data1D').increase_dim(self.scanner.n_axes)
655
+ viewers_enum.extend([ViewersEnum.Viewer1D.increase_dim(self.scanner.n_axes)
634
656
  for _ in range(len(self.settings['plot_options', 'plot_1d']['selected']))])
635
657
  data_names.extend(self.settings['plot_options', 'plot_1d']['selected'][:])
658
+ if not self.settings['scan_options', 'average_on_top']:
659
+
660
+ viewers_enum = viewers_enum + viewers_enum
661
+ data_names = data_names + [f'{data_name}_averaged' for data_name in data_names]
662
+
663
+ return viewers_enum, data_names, viewer2D_overload
664
+
665
+ def prepare_viewers(self):
666
+ """ Assert from selected options the number and type of needed viewers for live plotting
667
+ and prepare them on the live plot panel
668
+ """
669
+ viewers_enum, data_names, _ = self.check_number_type_viewers()
636
670
  self.live_plotter.prepare_viewers(viewers_enum, viewers_name=data_names)
637
671
 
638
672
  def update_status(self, txt: str, wait_time=0):
@@ -672,6 +706,7 @@ class DAQScan(QObject, ParameterManager):
672
706
  self.ui.set_scan_step_average(status.attribute[1] + 1)
673
707
 
674
708
  elif status.command == "Scan_done":
709
+
675
710
  self.modules_manager.reset_signals()
676
711
  self.live_timer.stop()
677
712
  self.ui.set_scan_done()
@@ -736,6 +771,7 @@ class DAQScan(QObject, ParameterManager):
736
771
  self.live_plotter.load_plot_data(group_0D=self.settings['plot_options', 'group0D'],
737
772
  average_axis=average_axis,
738
773
  average_index=self.ind_average,
774
+ separate_average= not self.settings['scan_options', 'average_on_top'],
739
775
  target_at=self.scanner.positions[self.ind_scan],
740
776
  last_step=(self.ind_scan ==
741
777
  self.scanner.positions.size - 1 and
@@ -767,11 +803,22 @@ class DAQScan(QObject, ParameterManager):
767
803
  f"limit in the config file ({config['scan']['steps_limit']}) or modify"
768
804
  f" your scan settings.")
769
805
 
806
+ _, _, viewer2D_overload = self.check_number_type_viewers()
807
+ if viewer2D_overload:
808
+ messagebox(text=
809
+ 'The number of live data chosen and the selected options '
810
+ 'will not be able to render fully on the 2D live viewers. Consider changing '
811
+ 'the options, such as "plot on top" for the averaging or "Group 0D data" '
812
+ 'or the number of selected data')
813
+ return False
814
+
770
815
  if self.modules_manager.Nactuators != self.scanner.n_axes:
771
816
  messagebox(
772
817
  text="There are not enough or too much selected move modules for this scan")
773
818
  return False
774
819
 
820
+ ## TODO the stuff about adaptive scans have to be moved into a dedicated extension. M
821
+ ## Most similat to the Bayesian one!
775
822
  if self.scanner.scan_sub_type == 'Adaptive':
776
823
  #todo include this in scanners objects for the adaptive scanners
777
824
  if len(self.modules_manager.get_selected_probed_data('0D')) == 0:
@@ -860,9 +907,15 @@ class DAQScan(QObject, ParameterManager):
860
907
  self.save_metadata(scan_node, 'scan_info')
861
908
 
862
909
  self._init_live()
910
+ Naverage = self.settings['scan_options', 'scan_average']
911
+ if Naverage > 1:
912
+ scan_shape = [Naverage]
913
+ scan_shape.extend(self.scanner.get_scan_shape())
914
+ else:
915
+ scan_shape = self.scanner.get_scan_shape()
863
916
  for det in self.modules_manager.detectors:
864
917
  det.module_and_data_saver = (
865
- module_saving.DetectorExtendedSaver(det, self.scanner.get_scan_shape()))
918
+ module_saving.DetectorExtendedSaver(det, scan_shape))
866
919
  self.module_and_data_saver.h5saver = self.h5saver # force the update as the h5saver ill also be set on each detectors
867
920
 
868
921
  # mandatory to deal with multithreads
@@ -1029,20 +1082,20 @@ class DAQScanAcquisition(QObject):
1029
1082
  self.set_ini_positions()
1030
1083
 
1031
1084
  elif command.command == "move_stages":
1032
- self.modules_manager.move_actuators(command.attribute)
1085
+ self.modules_manager.move_actuators(command.attribute, polling=False)
1033
1086
 
1034
1087
  def set_ini_positions(self):
1035
1088
  """ Set the actuators's positions totheir initial value as defined in the scanner """
1036
1089
  try:
1037
1090
  if self.scanner.scan_sub_type != 'Adaptive':
1038
- self.modules_manager.move_actuators(self.scanner.positions_at(0))
1091
+ self.modules_manager.move_actuators(self.scanner.positions_at(0), polling=False)
1039
1092
 
1040
1093
  except Exception as e:
1041
1094
  logger.exception(str(e))
1042
1095
 
1043
1096
  def start_acquisition(self):
1044
1097
  try:
1045
- #todo hoaw to apply newlayout to adaptive mode?
1098
+ #todo hoaw to apply newlayout to adaptive mode? => cannot has to be a new extension
1046
1099
 
1047
1100
  self.modules_manager.connect_actuators()
1048
1101
  self.modules_manager.connect_detectors()
@@ -1114,6 +1167,7 @@ class DAQScanAcquisition(QObject):
1114
1167
  # daq_scan wait time
1115
1168
  QThread.msleep(self.scan_settings.child('time_flow', 'wait_time').value())
1116
1169
 
1170
+ self.modules_manager.timeout_signal.disconnect()
1117
1171
  self.modules_manager.connect_actuators(False)
1118
1172
  self.modules_manager.connect_detectors(False)
1119
1173
 
@@ -1121,6 +1175,7 @@ class DAQScanAcquisition(QObject):
1121
1175
  attribute="Acquisition has finished"))
1122
1176
  self.status_sig.emit(utils.ThreadCommand("Scan_done"))
1123
1177
 
1178
+
1124
1179
  except Exception as e:
1125
1180
  logger.exception(str(e))
1126
1181
 
@@ -1156,7 +1211,8 @@ class DAQScanAcquisition(QObject):
1156
1211
  full_names: list = self.scan_settings['plot_options', 'plot_0d']['selected'][:]
1157
1212
  full_names.extend(self.scan_settings['plot_options', 'plot_1d']['selected'][:])
1158
1213
  data_temp = det_done_datas.get_data_from_full_names(full_names, deepcopy=False)
1159
- data_temp = data_temp.get_data_with_naxes_lower_than(2-len(indexes)) # maximum Data2D included nav indexes
1214
+ n_nav_axis_selection = 2-len(indexes) + 1 if self.Naverage > 1 else 2-len(indexes)
1215
+ data_temp = data_temp.get_data_with_naxes_lower_than(n_nav_axis_selection) # maximum Data2D included nav indexes
1160
1216
 
1161
1217
  self.scan_data_tmp.emit(ScanDataTemp(self.ind_scan, indexes, data_temp))
1162
1218
 
@@ -166,7 +166,7 @@ class DAQ_PID(CustomExt):
166
166
  def process_output(self, data: DataToExport):
167
167
  inputs: DataRaw = data.get_data_from_name('inputs')
168
168
  outputs: DataRaw = data.get_data_from_name('outputs')
169
- self.curr_points = [float(d) for d in inputs]
169
+ self.curr_points = [float(array[0]) for array in inputs]
170
170
  self.output_viewer.show_data(outputs)
171
171
  self.input_viewer.show_data(inputs)
172
172
 
@@ -137,38 +137,14 @@ class PIDModelGeneric:
137
137
 
138
138
 
139
139
  def main(xmlfile):
140
- from pymodaq.dashboard import DashBoard
141
- from pymodaq.utils.config import get_set_preset_path
140
+ from pymodaq.utils.gui_utils.loader_utils import load_dashboard_with_preset
142
141
  from pathlib import Path
143
142
  from qtpy import QtWidgets
143
+ from pymodaq_gui.utils.utils import mkQApp
144
144
 
145
145
  import sys
146
- app = QtWidgets.QApplication(sys.argv)
147
- win = QtWidgets.QMainWindow()
148
- area = DockArea()
149
- win.setCentralWidget(area)
150
- win.resize(1000, 500)
151
- win.setWindowTitle('PyMoDAQ Dashboard')
152
-
153
- dashboard = DashBoard(area)
154
- file = Path(get_set_preset_path()).joinpath(xmlfile)
155
- if file.exists():
156
- dashboard.set_preset_mode(file)
157
- # prog.load_scan_module()
158
- pid_area = DockArea()
159
- pid_window = QtWidgets.QMainWindow()
160
- pid_window.setCentralWidget(pid_area)
161
-
162
- prog = dashboard.load_pid_module(pid_window)
163
-
164
- else:
165
- msgBox = QtWidgets.QMessageBox()
166
- msgBox.setText(f"The default file specified in the configuration file does not exists!\n"
167
- f"{file}\n"
168
- f"Impossible to load the DAQ_PID Module")
169
- msgBox.setStandardButtons(msgBox.Ok)
170
- ret = msgBox.exec()
171
-
146
+ app = mkQApp('BeamSteering')
147
+ dashboard, extension, win = load_dashboard_with_preset(xmlfile, 'DAQ_PID')
172
148
  sys.exit(app.exec_())
173
149
 
174
150
 
@@ -180,7 +156,6 @@ def get_models(model_name=None):
180
156
  -------
181
157
  list: list of disct containting the name and python module of the found models
182
158
  """
183
- from pymodaq.extensions.pid.utils import PIDModelGeneric
184
159
  models_import = []
185
160
  discovered_models = list(get_entrypoints(group='pymodaq.pid_models'))
186
161
  discovered_models.extend(list(get_entrypoints(group='pymodaq.models')))
@@ -70,7 +70,7 @@ class LoaderPlotter:
70
70
  def load_data(self, filter_dims: List[Union[DataDim, str]] = None,
71
71
  filter_full_names: List[str] = None, remove_navigation: bool = True,
72
72
  group_0D=False, average_axis: int=None, average_index: int = 0,
73
- last_step=False):
73
+ last_step=False, separate_average=False):
74
74
  """Load Data from the h5 node of the dataloader and apply some filtering/manipulation before
75
75
  plotting
76
76
 
@@ -92,6 +92,8 @@ class LoaderPlotter:
92
92
  which step in the averaging process are we in.
93
93
  last_step: bool
94
94
  tells if this is the very last step of the (averaged) scan
95
+ separate_average: bool
96
+ Tells if the averaged data are to be plotted on the same data viewer panel or another one
95
97
 
96
98
  Returns
97
99
  -------
@@ -102,7 +104,8 @@ class LoaderPlotter:
102
104
  self.dataloader.load_all('/', self._data)
103
105
 
104
106
  if average_axis is not None:
105
- self.average_axis(average_axis, average_index, last_step=last_step)
107
+ self.average_axis(average_axis, average_index, last_step=last_step,
108
+ separate_average=separate_average)
106
109
 
107
110
  if filter_dims is not None:
108
111
  filter_dims[:] = [enum_checker(DataDim, dim) for dim in filter_dims]
@@ -113,14 +116,15 @@ class LoaderPlotter:
113
116
  filter_full_names]
114
117
 
115
118
  if group_0D: # 0D initial data
116
- self.group_0D_data()
119
+ self.group_0D_data(separate_average=separate_average)
117
120
 
118
121
  if remove_navigation:
119
122
  self.remove_navigation_axes()
120
123
 
121
124
  return self._data
122
125
 
123
- def average_axis(self, average_axis, average_index, last_step=False) -> None:
126
+ def average_axis(self, average_axis, average_index, last_step=False,
127
+ separate_average=False) -> None:
124
128
  """ Average the data along their average axis
125
129
 
126
130
  Parameters
@@ -132,7 +136,12 @@ class LoaderPlotter:
132
136
  which step in the averaging process are we in.
133
137
  last_step: bool
134
138
  tells if this is the very last step of the (averaged) scan
139
+ separate_average: bool
140
+ Tells if the averaged data are to be plotted on the same data viewer panel or another one
141
+
135
142
  """
143
+ if separate_average and average_index > 0:
144
+ averaged_data = DataToExport('Averaged')
136
145
  for ind, data in enumerate(self._data):
137
146
  current_data = data.inav[average_index, ...]
138
147
  if average_index > 0:
@@ -143,10 +152,16 @@ class LoaderPlotter:
143
152
  data_to_append = data.inav[0, ...]
144
153
  else:
145
154
  data_to_append = data.inav[0:average_index, ...].mean(axis=average_axis)
146
-
155
+ data_to_append.name = f'{data_to_append.name}_averaged'
147
156
  data_to_append.labels = [f'{label}_averaged' for label in data_to_append.labels]
148
- current_data.append(data_to_append)
157
+ if not (separate_average and average_index > 0):
158
+ current_data.append(data_to_append)
159
+ else:
160
+ averaged_data.append(data_to_append)
149
161
  self._data[ind] = current_data
162
+ if separate_average and average_index > 0:
163
+ self._data.append(averaged_data.data)
164
+
150
165
 
151
166
  def remove_navigation_axes(self):
152
167
  """Make the navigation axes as signal axes
@@ -159,18 +174,27 @@ class LoaderPlotter:
159
174
  data.transpose() # because usual ND data should be plotted here as 2D with the nav axes as the minor
160
175
  # (horizontal)
161
176
 
162
- def group_0D_data(self):
177
+ def group_0D_data(self, separate_average=False):
163
178
  """Group in a single DataFromPlugins all data that are initialy Data0D
164
179
 
165
180
  """
166
181
  data = self._data.get_data_from_sig_axes(0)
167
182
  if len(data) > 0:
168
183
  data0D_arrays = []
184
+ data0D_arrays_averaged = []
169
185
  labels = []
186
+ labels_averaged = []
170
187
  for dwa in data:
171
- data0D_arrays.extend(dwa.data)
172
- labels.extend([f'{dwa.get_full_name()}/{label}' for label in dwa.labels])
173
- self._data.remove(dwa)
188
+ if 'averaged' in dwa.name and separate_average:
189
+ data0D_arrays_averaged.extend(dwa.data)
190
+ labels_averaged.extend([f'{dwa.get_full_name()}/{label}' for label in dwa.labels])
191
+ self._data.remove(dwa)
192
+
193
+
194
+ else:
195
+ data0D_arrays.extend(dwa.data)
196
+ labels.extend([f'{dwa.get_full_name()}/{label}' for label in dwa.labels])
197
+ self._data.remove(dwa)
174
198
 
175
199
  data0D = DataFromPlugins(self.grouped_data0D_fullname.split('/')[1],
176
200
  data=data0D_arrays, labels=labels,
@@ -179,6 +203,15 @@ class LoaderPlotter:
179
203
  axes=dwa.axes, nav_indexes=dwa.nav_indexes,
180
204
  )
181
205
  self._data.append(data0D)
206
+ if 'averaged' in dwa.name and separate_average:
207
+ data0D_averaged = DataFromPlugins(
208
+ f"{self.grouped_data0D_fullname.split('/')[1]}_averaged",
209
+ data=data0D_arrays_averaged, labels=labels_averaged,
210
+ dim='DataND',
211
+ origin=self.grouped_data0D_fullname.split('/')[0],
212
+ axes=dwa.axes, nav_indexes=dwa.nav_indexes,
213
+ )
214
+ self._data.append(data0D_averaged)
182
215
 
183
216
  def load_plot_data(self, **kwargs):
184
217
  """Load and plot all data from the current H5Saver
@@ -9,9 +9,16 @@ from pymodaq_utils.warnings import deprecation_msg, user_warning
9
9
 
10
10
  from pymodaq_data.data import (DataRaw, DataWithAxes, DataToExport, DataCalculated, DataDim,
11
11
  DataSource, DataBase, Axis, NavAxis, DataDistribution, Q_, Unit,
12
- ) # imported here for backcompatibility
12
+ ) # imported here for backcompatibility. Will allow also the object serialization
13
+ # registration
13
14
 
14
15
 
16
+ from pymodaq_utils.serialize.factory import SerializableFactory, SerializableBase
17
+
18
+ ser_factory = SerializableFactory()
19
+
20
+
21
+ @ser_factory.register_decorator()
15
22
  class DataActuator(DataRaw):
16
23
  """Specialized DataWithAxes set with source as 'raw'.
17
24
  To be used for raw data generated by actuator plugins"""
@@ -40,6 +47,7 @@ class DataActuator(DataRaw):
40
47
  return super().__add__(other)
41
48
 
42
49
 
50
+ @ser_factory.register_decorator()
43
51
  class DataFromPlugins(DataRaw):
44
52
  """Specialized DataWithAxes set with source as 'raw'. To be used for raw data generated by Detector plugins
45
53
 
@@ -83,12 +91,14 @@ class DataFromPlugins(DataRaw):
83
91
  super().__init__(*args, **kwargs)
84
92
 
85
93
 
94
+ @ser_factory.register_decorator()
86
95
  class DataScan(DataToExport):
87
96
  """Specialized DataToExport.To be used for data to be saved """
88
97
  def __init__(self, name: str, data: List[DataWithAxes] = [], **kwargs):
89
98
  super().__init__(name, data, **kwargs)
90
99
 
91
100
 
101
+ @ser_factory.register_decorator()
92
102
  class DataToActuators(DataToExport):
93
103
  """ Particular case of a DataToExport adding one named parameter to indicate what kind of change
94
104
  should be applied to the actuators, absolute or relative
@@ -115,4 +125,3 @@ class DataToActuators(DataToExport):
115
125
 
116
126
  def __repr__(self):
117
127
  return f'{super().__repr__()}: {self.mode}'
118
-
@@ -39,6 +39,8 @@ def load_dashboard_with_preset(preset_name: str, extension_name: str) -> \
39
39
  # win.setVisible(False)
40
40
  dashboard = DashBoard(area)
41
41
 
42
+ preset_name = Path(preset_name).stem
43
+
42
44
  file = Path(get_set_preset_path()).joinpath(f"{preset_name}.xml")
43
45
 
44
46
  if file is not None and file.exists():
@@ -11,7 +11,7 @@ import xml.etree.ElementTree as ET
11
11
 
12
12
 
13
13
  import numpy as np
14
-
14
+ from pymodaq_utils.logger import set_logger, get_module_name
15
15
  from pymodaq_utils.abstract import ABCMeta, abstract_attribute, abstractmethod
16
16
  from pymodaq_utils.utils import capitalize
17
17
  from pymodaq_data.data import Axis, DataDim, DataWithAxes, DataToExport, DataDistribution
@@ -28,6 +28,9 @@ if TYPE_CHECKING:
28
28
  from pymodaq.extensions.daq_logger.h5logging import H5Logger
29
29
 
30
30
 
31
+ logger = set_logger(get_module_name(__file__))
32
+
33
+
31
34
  class ModuleSaver(metaclass=ABCMeta):
32
35
  """Abstract base class to save info and data from main modules (DAQScan, DAQViewer, DAQMove, ...)"""
33
36
  group_type: GroupType = abstract_attribute()
@@ -374,7 +377,7 @@ class ScanSaver(ModuleSaver):
374
377
  try:
375
378
  detector.insert_data(indexes, where=self._module_group, distribution=distribution)
376
379
  except Exception as e:
377
- pass
380
+ logger.exception(f'Cannot insert data: {str(e)}')
378
381
 
379
382
 
380
383
  class LoggerSaver(ScanSaver):
@@ -17,8 +17,7 @@ from pymodaq_gui.parameter import Parameter
17
17
 
18
18
  from pymodaq.utils.leco.leco_director import LECODirector, leco_parameters
19
19
  from pymodaq.utils.leco.director_utils import ActuatorDirector
20
- from pymodaq.utils.tcp_ip.serializer import DeSerializer
21
-
20
+ from pymodaq_utils.serialize.serializer_legacy import DeSerializer
22
21
 
23
22
  class DAQ_Move_LECODirector(LECODirector, DAQ_Move_base):
24
23
  """A control module, which in the dashboard, allows to control a remote Move module.
@@ -6,8 +6,9 @@ from easydict import EasyDict as edict
6
6
  from pymodaq.control_modules.viewer_utility_classes import DAQ_Viewer_base, comon_parameters, main
7
7
 
8
8
  from pymodaq_utils.utils import ThreadCommand, getLineInfo
9
+
9
10
  from pymodaq_gui.parameter import Parameter
10
- from pymodaq.utils.tcp_ip.serializer import DeSerializer
11
+ from pymodaq_utils.serialize.serializer_legacy import DeSerializer
11
12
 
12
13
  from pymodaq.utils.leco.leco_director import LECODirector, leco_parameters
13
14
  from pymodaq.utils.leco.director_utils import DetectorDirector
@@ -1,8 +1,9 @@
1
-
2
1
  import random
3
-
4
2
  from typing import Callable, Sequence, List
5
3
 
4
+ from pymodaq_utils.enums import StrEnum
5
+ from typing import Callable, Sequence, List, Optional, Union
6
+
6
7
  import pymodaq_gui.parameter.utils as putils
7
8
  # object used to send info back to the main thread:
8
9
  from pymodaq_utils.utils import ThreadCommand
@@ -14,7 +15,7 @@ from pymodaq.utils.leco.pymodaq_listener import PymodaqListener
14
15
 
15
16
  leco_parameters = [
16
17
  {'title': 'Actor name:', 'name': 'actor_name', 'type': 'str', 'value': "actor_name",
17
- 'text': 'Name of the actor plugin to communicate with.'},
18
+ 'tip': 'Name of the actor plugin to communicate with.'},
18
19
  ]
19
20
 
20
21
 
@@ -1,11 +1,6 @@
1
1
 
2
- try:
3
- from enum import StrEnum # type: ignore
4
- except ImportError:
5
- from enum import Enum
2
+ from pymodaq_utils.enums import StrEnum
6
3
 
7
- class StrEnum(str, Enum):
8
- pass
9
4
  import logging
10
5
  from threading import Event
11
6
  from typing import Optional, Union, List, Type
@@ -2,10 +2,11 @@ from __future__ import annotations
2
2
  import subprocess
3
3
  import sys
4
4
  from typing import Any, Optional, Union, get_args, TypeVar
5
- from pymodaq_data import data
5
+
6
6
  from pymodaq.utils import data
7
7
  # import also the DeSerializer for easier imports in dependents
8
8
  from pymodaq_utils.serialize.serializer_legacy import Serializer, DeSerializer, SerializableFactory
9
+
9
10
  # type: ignore # noqa
10
11
  from pymodaq_utils.logger import set_logger
11
12
 
@@ -14,7 +15,6 @@ logger = set_logger('leco_utils')
14
15
  ser_factory = SerializableFactory()
15
16
  JSON_TYPES = Union[str, int, float]
16
17
 
17
- SERIALIZABLE = ser_factory.get_serializables()
18
18
 
19
19
 
20
20
  def serialize_object(pymodaq_object: Union[SERIALIZABLE, Any]) -> Union[str, Any]:
@@ -26,6 +26,13 @@ def serialize_object(pymodaq_object: Union[SERIALIZABLE, Any]) -> Union[str, Any
26
26
  #is not serializable
27
27
 
28
28
 
29
+ ## this form below is to be compatible with python <= 3.10
30
+ ## for py>= 3.11 this could be written SERIALIZABLE = Union[ser_factory.get_serializables()]
31
+ SERIALIZABLE = Union[ser_factory.get_serializables()[0]]
32
+ for klass in ser_factory.get_serializables()[1:]:
33
+ SERIALIZABLE = Union[SERIALIZABLE, klass]
34
+
35
+
29
36
  def binary_serialization(
30
37
  pymodaq_object: Union[SERIALIZABLE, Any],
31
38
  ) -> tuple[Optional[Any], Optional[list[bytes]]]:
@@ -374,12 +374,12 @@ class ModulesManager(QObject, ParameterManager):
374
374
  sig.connect(slot)
375
375
  else:
376
376
 
377
- for sig in [mod.grab_done_signal for mod in self.detectors_all]:
377
+ for sig in [mod.grab_done_signal for mod in self.detectors]:
378
378
  try:
379
379
  sig.disconnect(slot)
380
380
  except TypeError as e:
381
381
  # means the slot was not previously connected
382
- logger.info(str(e))
382
+ logger.info(f'Could not disconnect grab signal from the {slot} slot', stacklevel=2)
383
383
 
384
384
  self.detectors_connected = connect
385
385
 
@@ -7,7 +7,7 @@ Created the 20/10/2023
7
7
 
8
8
  from pymodaq_utils.utils import deprecation_msg
9
9
 
10
- from pymodaq_data.serialize.serializer_legacy import Serializer, DeSerializer, SocketString, Socket
10
+ from pymodaq_utils.serialize.serializer_legacy import Serializer, DeSerializer, SocketString, Socket
11
11
 
12
12
  deprecation_msg('Importing Serializer, DeSerializer from pymodaq is deprecated in PyMoDAQ >= 5,'
13
13
  'import them from pymodaq_data.serialize.serializer')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes