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
@@ -1,5 +1,7 @@
1
1
  import time
2
2
  from functools import partial # needed for the button to sync setpoint with currpoint
3
+ from typing import Dict, List, TYPE_CHECKING
4
+
3
5
  import numpy as np
4
6
 
5
7
  from qtpy import QtGui, QtWidgets
@@ -9,13 +11,14 @@ from simple_pid import PID
9
11
 
10
12
  from pymodaq_utils.logger import set_logger, get_module_name
11
13
  from pymodaq_utils.utils import ThreadCommand, find_dict_in_list_from_key_val
14
+ from pymodaq.utils.exceptions import DetectorError, ActuatorError, PIDError
12
15
 
13
16
  from pymodaq_gui.parameter import utils as putils
14
17
  from pymodaq_gui.parameter import Parameter, ParameterTree
15
18
  from pymodaq_gui.plotting.data_viewers.viewer0D import Viewer0D
16
19
  from pymodaq_gui.utils.widgets import QLED, LabelWithFont, SpinBox
17
20
  from pymodaq_gui.utils.dock import DockArea, Dock
18
- from pymodaq_gui.utils.custom_app import CustomApp
21
+
19
22
 
20
23
  from pymodaq_data.data import DataToExport, DataCalculated, DataRaw
21
24
  from pymodaq_utils.config import Config
@@ -23,6 +26,11 @@ from pymodaq_utils.config import Config
23
26
  from pymodaq.utils.managers.modules_manager import ModulesManager
24
27
  from pymodaq.extensions.pid.utils import get_models
25
28
  from pymodaq.utils.data import DataActuator, DataToActuators
29
+ from pymodaq.extensions.pid.actuator_controller import PIDController
30
+ from pymodaq.extensions.utils import CustomExt
31
+
32
+ if TYPE_CHECKING:
33
+ from pymodaq.control_modules.daq_move import DAQ_Move
26
34
 
27
35
 
28
36
  config = Config()
@@ -38,7 +46,7 @@ def convert_output_limits(lim_min=-10., min_status=False, lim_max=10., max_statu
38
46
  return output
39
47
 
40
48
 
41
- class DAQ_PID(CustomApp):
49
+ class DAQ_PID(CustomExt):
42
50
  """
43
51
  """
44
52
  command_pid = Signal(ThreadCommand)
@@ -170,7 +178,7 @@ class DAQ_PID(CustomApp):
170
178
  self.set_action_enabled('run', enable)
171
179
  self.set_action_enabled('pause', enable)
172
180
 
173
- def setup_menu(self):
181
+ def setup_menu(self, menubar: QtWidgets.QMenuBar = None):
174
182
  '''
175
183
  to be subclassed
176
184
  create menu for actions contained into the self.actions_manager, for instance:
@@ -241,6 +249,7 @@ class DAQ_PID(CustomApp):
241
249
  logger.debug('connecting actions and other')
242
250
  self.connect_action('quit', self.quit_fun, )
243
251
  self.connect_action('ini_model', self.ini_model)
252
+ self.connect_action('create_setp_actuators', self.create_setp_actuators)
244
253
  self.connect_action('ini_pid', self.ini_PID)
245
254
  self.connect_action('run', self.run_PID)
246
255
  self.connect_action('pause', self.pause_PID)
@@ -252,12 +261,21 @@ class DAQ_PID(CustomApp):
252
261
  self.add_widget('model_label', QtWidgets.QLabel, 'Init Model:')
253
262
  self.add_action('ini_model', 'Init Model', 'ini', tip='Initialize the selected model: algo/data conversion')
254
263
  self.add_widget('model_led', QLED, toolbar=self.toolbar)
264
+
265
+ self.add_action('create_setp_actuators', 'Create SetPoint Actuators', 'Add_Step',
266
+ tip='Create a DAQ_Move Control Module for each SetPoint allowing to'
267
+ 'control them from the DashBoard, therefore within other extensions')
268
+
255
269
  self.add_widget('model_label', QtWidgets.QLabel, 'Init PID Runner:')
256
- self.add_action('ini_pid', 'Init the PID loop', 'ini', tip='Init the PID thread', checkable=True)
270
+ self.add_action('ini_pid', 'Init the PID loop', 'ini', tip='Init the PID thread',
271
+ checkable=True)
257
272
  self.add_widget('pid_led', QLED, toolbar=self.toolbar)
258
- self.add_action('run', 'Run The PID loop', 'run2', tip='run or stop the pid loop', checkable=True)
259
- self.add_action('pause', 'Pause the PID loop', 'pause', tip='Pause the PID loop', checkable=True)
273
+ self.add_action('run', 'Run The PID loop', 'run2', tip='run or stop the pid loop',
274
+ checkable=True)
275
+ self.add_action('pause', 'Pause the PID loop', 'pause', tip='Pause the PID loop',
276
+ checkable=True)
260
277
  self.set_action_checked('pause', True)
278
+ self.set_action_enabled('create_setp_actuators', False)
261
279
  logger.debug('actions set')
262
280
 
263
281
  def setup_docks(self):
@@ -297,6 +315,17 @@ class DAQ_PID(CustomApp):
297
315
 
298
316
  self.dock_pid.addWidget(widget)
299
317
 
318
+ def create_setp_actuators(self):
319
+ # Now that we have the module manager, load PID if it is checked in managers
320
+ try:
321
+ for setp in self.model_class.setpoints_names:
322
+ self.dashboard.add_move_from_extension(setp, 'PID', PIDController(self))
323
+ self.set_action_enabled('create_setp_actuators', False)
324
+
325
+ except Exception as e:
326
+ raise PIDError('Could not load the PID extension and create setpoints actuators'
327
+ f'{str(e)}')
328
+
300
329
  def get_set_model_params(self, model_name):
301
330
  self.settings.child('models', 'model_params').clearChildren()
302
331
  models = get_models()
@@ -355,6 +384,7 @@ class DAQ_PID(CustomApp):
355
384
  self.enable_controls_pid(True)
356
385
  self.get_action('model_led').set_as_true()
357
386
  self.set_action_enabled('ini_model', False)
387
+ self.set_action_enabled('create_setp_actuators', True)
358
388
 
359
389
  except Exception as e:
360
390
  logger.exception(str(e))
@@ -368,10 +398,10 @@ class DAQ_PID(CustomApp):
368
398
  for ind, sp in enumerate(self.setpoints_sb):
369
399
  sp.setValue(values[ind])
370
400
 
371
- def setpoints_external(self, values_dict):
401
+ def setpoints_external(self, values_dict: Dict[str, DataActuator]):
372
402
  for key in values_dict:
373
403
  index = self.model_class.setpoints_names.index(key)
374
- self.setpoints_sb[index].setValue(values_dict[key])
404
+ self.setpoints_sb[index].setValue(values_dict[key].value())
375
405
 
376
406
  @property
377
407
  def curr_points(self):
@@ -643,38 +673,16 @@ class PIDRunner(QObject):
643
673
 
644
674
 
645
675
  if __name__ == '__main__':
646
- import sys
647
- from pathlib import Path
648
- from pymodaq.utils.daq_utils import get_set_preset_path
649
-
650
- app = QtWidgets.QApplication(sys.argv)
651
- if config['style']['darkstyle']:
652
- import qdarkstyle
653
- app.setStyleSheet(qdarkstyle.load_stylesheet())
654
-
655
- from pymodaq.dashboard import DashBoard
656
-
657
- win = QtWidgets.QMainWindow()
658
- area = DockArea()
659
- win.setCentralWidget(area)
660
- win.resize(1000, 500)
661
- win.setWindowTitle('PyMoDAQ Dashboard')
662
-
663
- dashboard = DashBoard(area)
664
- pid = None
665
- file = Path(get_set_preset_path()).joinpath(f"{config('presets', 'default_preset_for_pid')}.xml")
666
- if file.exists():
667
- dashboard.set_preset_mode(file)
668
- pid = dashboard.load_pid_module()
669
- else:
670
- msgBox = QtWidgets.QMessageBox()
671
- msgBox.setText(f"The default file specified in the configuration file does not exists!\n"
672
- f"{file}\n"
673
- f"Impossible to load the DAQ_PID Module")
674
- msgBox.setStandardButtons(msgBox.Ok)
675
- ret = msgBox.exec()
676
-
677
- sys.exit(app.exec_())
676
+ from pymodaq_gui.utils.utils import mkQApp
677
+ from pymodaq.utils.gui_utils.loader_utils import load_dashboard_with_preset
678
+
679
+ app = mkQApp('DAQ_PID')
680
+ preset_file_name = config('presets', f'default_preset_for_pid')
681
+
682
+ dashboard, extension, win = load_dashboard_with_preset(preset_file_name, 'DAQ_PID')
683
+
684
+ app.exec()
685
+
678
686
 
679
687
 
680
688
 
@@ -27,6 +27,7 @@ DAQ_2DViewer_Det_types = get_plugins('daq_2Dviewer')
27
27
  DAQ_NDViewer_Det_types = get_plugins('daq_NDviewer')
28
28
 
29
29
 
30
+
30
31
  class DataToActuatorPID(DataToActuators):
31
32
 
32
33
  def __init__(self, *args, **kwargs):
@@ -181,8 +182,8 @@ def get_models(model_name=None):
181
182
  """
182
183
  from pymodaq.extensions.pid.utils import PIDModelGeneric
183
184
  models_import = []
184
- discovered_models = get_entrypoints(group='pymodaq.pid_models')
185
- discovered_models = get_entrypoints(group='pymodaq.models')
185
+ discovered_models = list(get_entrypoints(group='pymodaq.pid_models'))
186
+ discovered_models.extend(list(get_entrypoints(group='pymodaq.models')))
186
187
  if len(discovered_models) > 0:
187
188
  for pkg in discovered_models:
188
189
  try:
@@ -8,14 +8,22 @@ import importlib
8
8
  from pathlib import Path
9
9
  import pkgutil
10
10
  import warnings
11
+ from typing import Union, TYPE_CHECKING
11
12
 
12
- from pymodaq_utils.utils import get_entrypoints
13
+ from qtpy import QtCore, QtWidgets
13
14
 
15
+ from pymodaq_gui.utils.dock import DockArea
16
+ from pymodaq_utils.utils import get_entrypoints
14
17
  from pymodaq_utils import logger as logger_module
18
+ from pymodaq_gui.utils.custom_app import CustomApp
15
19
 
20
+ from pymodaq.utils.managers.modules_manager import ModulesManager
16
21
 
17
22
  logger = logger_module.set_logger(logger_module.get_module_name(__file__))
18
23
 
24
+ if TYPE_CHECKING:
25
+ from pymodaq.dashboard import DashBoard
26
+
19
27
 
20
28
  def get_ext_modules(path: Path):
21
29
  modules = []
@@ -47,13 +55,39 @@ def get_extensions():
47
55
  module = importlib.import_module(pkg.value)
48
56
  modules = get_ext_modules(Path(module.__path__[0]).joinpath('extensions'))
49
57
  for mod in modules:
50
- mod_in = importlib.import_module(f'{pkg.value}.extensions.{mod}')
51
- if hasattr(mod_in, 'EXTENSION_NAME'):
52
- extension_import.append({'pkg': pkg.value, 'module': mod, 'name': mod_in.EXTENSION_NAME,
53
- 'class_name': mod_in.CLASS_NAME})
58
+ try:
59
+ mod_in = importlib.import_module(f'{pkg.value}.extensions.{mod}')
60
+ if hasattr(mod_in, 'EXTENSION_NAME'):
61
+ extension_import.append({'pkg': pkg.value, 'module': mod,
62
+ 'name': mod_in.EXTENSION_NAME,
63
+ 'class_name': mod_in.CLASS_NAME})
54
64
 
55
- except Exception as e: # pragma: no cover
56
- logger.warning(f'Impossible to import the {pkg.value}.extensions.{mod} extension: {str(e)}')
65
+ except Exception as e: # pragma: no cover
66
+ logger.warning(f'Impossible to import the {pkg.value}.extensions.{mod} extension: '
67
+ f'{str(e)}')
68
+ except Exception as e:
69
+ logger.warning(f'Impossible to import the {pkg.value} package: '
70
+ f'{str(e)}')
57
71
 
58
72
  return extension_import
59
73
 
74
+
75
+ class CustomExt(CustomApp):
76
+
77
+ def __init__(self, parent: Union[DockArea, QtWidgets.QWidget], dashboard: 'DashBoard'):
78
+ super().__init__(parent)
79
+
80
+ self.dashboard = dashboard
81
+
82
+ @property
83
+ def modules_manager(self) -> ModulesManager:
84
+ """useful tool to interact with DAQ_Moves and DAQ_Viewers
85
+
86
+ Will be available if a DashBoard has been set
87
+
88
+ Returns
89
+ -------
90
+ ModulesManager
91
+ """
92
+ if self.dashboard is not None:
93
+ return self.dashboard.modules_manager
@@ -23,6 +23,7 @@ def setup(path: Path):
23
23
  name=PLUGIN_NAME,
24
24
  description=config['plugin-info']['description'],
25
25
  long_description=long_description,
26
+ long_description_content_type='text/x-rst',
26
27
  license=config['plugin-info']['license'],
27
28
  url=config['plugin-info']['package-url'],
28
29
  author=config['plugin-info']['author'],
pymodaq/updater.py ADDED
@@ -0,0 +1,107 @@
1
+ import argparse
2
+ import subprocess
3
+ import sys
4
+ import time
5
+ import logging
6
+
7
+ from pathlib import Path
8
+
9
+ from pymodaq_utils.logger import set_logger, get_module_name
10
+
11
+ logger = set_logger(get_module_name(__file__))
12
+ logger.addHandler(logging.StreamHandler(sys.stdout))
13
+
14
+ def wait_for_parent():
15
+ '''
16
+ A function to wait for its parent to terminate execution.
17
+
18
+ In order to achieve that, this process has to be started with
19
+ stdin replaced by a piped stream from its parent. When the
20
+ parent terminates, stdin will close and either return from read
21
+ or throw an exception. De facto creating a way to wait for its
22
+ parent's termination.
23
+
24
+ It then sleep for 2 seconds, to let the parent process complete
25
+ termination.
26
+
27
+ CAUTION: If the process was not started by piping stdin AND
28
+ the --wait option is set, this function will hang forever.
29
+
30
+ We could use `psutil` or a similar lib to check for parent's process
31
+ existance with its pid.
32
+ '''
33
+
34
+ logger.info("Waiting for parent process to stop.")
35
+ try:
36
+ sys.stdin.read()
37
+ except:
38
+ pass
39
+ logger.debug("Parent process closed stdin")
40
+ time.sleep(2)
41
+ logger.info("Parent process stopped.")
42
+
43
+ def process_args():
44
+ '''
45
+ Declare arguments for updater.py, parse them and returns them in an object.
46
+ The arguments are:
47
+ --file <file> to request a python program to (re)start after update if needed (optional)
48
+ --wait to wait for the starting process to terminate before updating (optional, defaults to False)
49
+ packages the package list to install/update (they should contain the version in a pip accepted format)
50
+ '''
51
+ parser = argparse.ArgumentParser(description='Update pymodaq using pip.')
52
+ parser.add_argument('--file', type=str, help='the pymodaq script to restart after update')
53
+ parser.add_argument("--wait", action="store_true", help="enable waiting for pymodaq to finish mode (default is disabled).")
54
+ parser.add_argument('packages', type=str, nargs='+', help='package list')
55
+ return parser.parse_args()
56
+
57
+ def restart_if_command_launch(args):
58
+ '''
59
+ Try to detect if this process if launched using the declared command (i.e. `pymodaq_updater`)
60
+ or using the script file (`updater.py`). If it uses the command, it restart the process to
61
+ force it to use the script file, thus preventing a locked file during update on windows systems.
62
+ '''
63
+ python_file_path = Path(__file__) # Should be the path to `updater.py`
64
+ started_path = Path(sys.argv[0]) # Either `updater.py` or `pymodaq_updater`
65
+
66
+ # If they're different we'll restart using the script file
67
+ if started_path.absolute() != python_file_path.absolute():
68
+ logger.info("Started as pymodaq_updater, need to restart using python to prevent lock.")
69
+ # We HAVE to wait for this process to stop in the restarted process
70
+ new_args = ['--wait'] + sys.argv[1:]
71
+ if args.wait:
72
+ wait_for_parent()
73
+
74
+ subprocess.Popen([sys.executable, str(python_file_path.absolute())] + new_args, stdin=subprocess.PIPE)
75
+ sys.exit(0)
76
+
77
+ def main():
78
+ args = process_args()
79
+ logger.info(f"Arguments processed: {args}")
80
+
81
+ restart_if_command_launch(args)
82
+
83
+ if args.wait:
84
+ wait_for_parent()
85
+
86
+ packages_str = ', '.join(args.packages)
87
+ logger.info(f'Updating packages: {packages_str}')
88
+
89
+ with subprocess.Popen([sys.executable, '-m', 'pip', 'install'] + args.packages, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as pip:
90
+ for line in pip.stdout:
91
+ # Can't decode as some characters are not valid and make the whole process fail
92
+ logger.info(line[:-1])
93
+ ret_code = pip.wait()
94
+
95
+
96
+ if ret_code == 0:
97
+ logger.info(f'Succesfully updated {packages_str}')
98
+ else:
99
+ logger.error(f'Error while updating {packages_str}, pip returned {ret_code}')
100
+
101
+ if args.file is not None:
102
+ logger.info(f"Restarting {args.file} script after update.")
103
+ subprocess.Popen([sys.executable, args.file])
104
+
105
+
106
+ if __name__ == "__main__":
107
+ main()
@@ -6,8 +6,7 @@ from qtpy import QtGui, QtWidgets
6
6
  from qtpy.QtCore import Qt, QObject, QTimer
7
7
 
8
8
 
9
- from pymodaq_gui.utils import DockArea, Dock
10
- from pymodaq_gui.QtDesigner_Ressources import QtDesigner_ressources_rc
9
+ from pymodaq_gui.utils.dock import DockArea, Dock
11
10
 
12
11
 
13
12
  class PushButtonShortcut(QtWidgets.QPushButton):
@@ -64,7 +63,7 @@ class ChronoTimer(QObject):
64
63
 
65
64
  self.dock_chrono_timer.setAutoFillBackground(True)
66
65
  palette = self.dock_chrono_timer.palette()
67
- palette.setColor(palette.Background, QtGui.QColor(0, 0, 0))
66
+ palette.setColor(palette.Window, QtGui.QColor(0, 0, 0))
68
67
  self.dock_chrono_timer.setPalette(palette)
69
68
 
70
69
  self.time_lcd = QtWidgets.QLCDNumber(8)
@@ -92,7 +91,7 @@ class ChronoTimer(QObject):
92
91
  self.controls_layout.addWidget(hor_widget)
93
92
 
94
93
  icon = QtGui.QIcon()
95
- icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/run2.png"), QtGui.QIcon.Normal,
94
+ icon.addPixmap(QtGui.QPixmap("icons:run2.png"), QtGui.QIcon.Normal,
96
95
  QtGui.QIcon.Off)
97
96
  self.start_pb = PushButtonShortcut(icon, 'Start',
98
97
  shortcut='Home', shortcut_widget=self.area)
@@ -102,7 +101,7 @@ class ChronoTimer(QObject):
102
101
  hor_layout.addWidget(self.start_pb)
103
102
 
104
103
  icon = QtGui.QIcon()
105
- icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/pause.png"), QtGui.QIcon.Normal,
104
+ icon.addPixmap(QtGui.QPixmap("icons:pause.png"), QtGui.QIcon.Normal,
106
105
  QtGui.QIcon.Off)
107
106
  self.pause_pb = PushButtonShortcut(icon, 'Pause',
108
107
  shortcut='Ctrl+p', shortcut_widget=self.area)
@@ -112,7 +111,7 @@ class ChronoTimer(QObject):
112
111
  hor_layout.addWidget(self.pause_pb)
113
112
 
114
113
  icon = QtGui.QIcon()
115
- icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Refresh2.png"), QtGui.QIcon.Normal,
114
+ icon.addPixmap(QtGui.QPixmap("icons:Refresh2.png"), QtGui.QIcon.Normal,
116
115
  QtGui.QIcon.Off)
117
116
  self.reset_pb = PushButtonShortcut(icon, 'Reset',
118
117
  shortcut='F5', shortcut_widget=self.area)
@@ -184,7 +183,7 @@ class ChronoTimer(QObject):
184
183
  # lcd.setPalette(QtGui.QPalette(Qt.red))
185
184
  if hasattr(Qt, color):
186
185
  palette.setBrush(palette.WindowText, getattr(Qt, color))
187
- palette.setColor(palette.Background, QtGui.QColor(0, 0, 0))
186
+ palette.setColor(palette.Window, QtGui.QColor(0, 0, 0))
188
187
  lcd.setPalette(palette)
189
188
 
190
189
 
@@ -5,9 +5,11 @@ import pkgutil
5
5
  import platform
6
6
  from pathlib import Path
7
7
 
8
- from pymodaq_utils import logger as logger_module
9
8
  from pymodaq_utils.config import Config
10
- from pymodaq_utils.utils import get_entrypoints, ThreadCommand, getLineInfo
9
+ from pymodaq_utils.utils import get_entrypoints, ThreadCommand, getLineInfo, find_keys_from_val, is_64bits, timer # for backcompat
10
+ from pymodaq_utils.logger import set_logger, get_module_name # for backcompat
11
+
12
+ from pymodaq.utils.data import DataFromPlugins # for backcompat
11
13
 
12
14
  from pymodaq.utils.config import get_set_preset_path
13
15
 
@@ -18,7 +20,7 @@ else:
18
20
  from functools import lru_cache as cache
19
21
 
20
22
 
21
- logger = logger_module.set_logger(logger_module.get_module_name(__file__))
23
+ logger = set_logger(get_module_name(__file__))
22
24
 
23
25
  config = Config()
24
26
 
@@ -122,6 +124,7 @@ def get_instrument_plugins(): # pragma: no cover
122
124
  except Exception as e:
123
125
  logger.debug(f'Impossible to import PID utility plugin: {str(e)}')
124
126
 
127
+ plugins_import.sort(key=lambda mod: mod['name'])
125
128
  return plugins_import
126
129
 
127
130
 
pymodaq/utils/data.py CHANGED
@@ -1,13 +1,15 @@
1
1
  import numpy as np
2
2
  import numbers
3
3
  import warnings
4
+ import copy
4
5
 
5
6
  from typing import List
6
7
 
7
8
  from pymodaq_utils.warnings import deprecation_msg, user_warning
8
9
 
9
10
  from pymodaq_data.data import (DataRaw, DataWithAxes, DataToExport, DataCalculated, DataDim,
10
- DataSource, DataBase, Axis, NavAxis)
11
+ DataSource, DataBase, Axis, NavAxis, DataDistribution, Q_, Unit,
12
+ ) # imported here for backcompatibility
11
13
 
12
14
 
13
15
  class DataActuator(DataRaw):
@@ -24,25 +26,18 @@ class DataActuator(DataRaw):
24
26
 
25
27
  def __repr__(self):
26
28
  if self.dim.name == 'Data0D':
27
- return f'<{self.__class__.__name__} ({self.data[0][0]})>'
29
+ return f'<{self.__class__.__name__} ({self.data[0][0]} {self.units})>'
28
30
  else:
29
- return f'<{self.__class__.__name__} ({self.shape})>'
31
+ return f'<{self.__class__.__name__} ({self.shape} {self.units})>'
30
32
 
31
- def value(self) -> float:
32
- """Returns the underlying float value (of the first elt in the data list) if this data
33
- holds only a float otherwise returns a mean of the underlying data"""
34
- if self.length == 1 and self.size == 1:
35
- return float(self.data[0][0])
36
- else:
37
- return float(np.mean(self.data))
33
+ def __add__(self, other: object):
34
+ if isinstance(other, numbers.Number) and self.length == 1 and self.size == 1:
35
+ new_data = copy.deepcopy(self)
36
+ new_data = new_data + DataActuator(data=other)
37
+ return new_data
38
38
 
39
- def values(self) -> List[float]:
40
- """Returns the underlying float value (for each data array in the data list) if this data
41
- holds only a float otherwise returns a mean of the underlying data"""
42
- if self.length == 1 and self.size == 1:
43
- return [float(data_array[0]) for data_array in self.data]
44
39
  else:
45
- return [float(np.mean(data_array)) for data_array in self.data]
40
+ return super().__add__(other)
46
41
 
47
42
 
48
43
  class DataFromPlugins(DataRaw):
pymodaq/utils/enums.py ADDED
@@ -0,0 +1,6 @@
1
+ from pymodaq_utils.enums import *
2
+
3
+ from pymodaq_utils.warnings import deprecation_msg
4
+
5
+ deprecation_msg('Importing enums stuff from pymodaq is deprecated in pymodaq>5.0.0,'
6
+ 'please use the pymodaq_utils.enums module')
@@ -5,14 +5,35 @@ from qtpy import QtWidgets
5
5
  from pymodaq.dashboard import DashBoard
6
6
  from pymodaq.utils.gui_utils import DockArea
7
7
  from pymodaq.utils.config import get_set_preset_path
8
+ from pymodaq.extensions.utils import CustomExt
8
9
 
9
10
 
10
- def load_dashboard_with_preset(preset_name: str, extension_name: str):
11
+ def load_dashboard_with_preset(preset_name: str, extension_name: str) -> \
12
+ (DashBoard, CustomExt, QtWidgets.QMainWindow):
13
+ """ Load the Dashboard using a given preset then load an extension
14
+
15
+ Parameters
16
+ ----------
17
+ preset_name: str
18
+ The filename (without extension) defining the preset to be loaded in the Dashboard
19
+ extension_name: str
20
+ The name of the extension. Either the builtins ones:
21
+ * 'DAQScan'
22
+ * 'DAQLogger'
23
+ * 'DAQ_PID'
24
+ * 'Bayesian'
25
+
26
+ or the ones defined within a plugin
27
+
28
+ Returns
29
+ -------
30
+
31
+ """
11
32
  win = QtWidgets.QMainWindow()
12
33
  area = DockArea()
13
34
  win.setCentralWidget(area)
14
35
  win.resize(1000, 500)
15
- win.setWindowTitle('PyMoDAQ Dashboard')
36
+ win.setWindowTitle('extension_name')
16
37
  win.show()
17
38
 
18
39
  # win.setVisible(False)
@@ -26,6 +47,10 @@ def load_dashboard_with_preset(preset_name: str, extension_name: str):
26
47
  extension = dashboard.load_scan_module()
27
48
  elif extension_name == 'DAQLogger':
28
49
  extension = dashboard.load_log_module()
50
+ elif extension_name == 'DAQ_PID':
51
+ extension = dashboard.load_pid_module()
52
+ elif extension_name == 'Bayesian':
53
+ extension = dashboard.load_bayesian()
29
54
  else:
30
55
  extension = dashboard.load_extension_from_name(extension_name)
31
56
  else:
@@ -1,21 +1,18 @@
1
- import sys
2
-
3
- from qtpy.QtCore import QObject, Signal, QEvent, QBuffer, QIODevice, Qt
4
- from qtpy import QtWidgets, QtCore, QtGui
5
-
6
- from pathlib import Path
7
1
  from pymodaq_utils.config import Config
8
2
  from pymodaq_utils.logger import set_logger, get_module_name
9
3
 
4
+ from pymodaq_gui.utils.splash import get_splash_sc
5
+
6
+
10
7
  config = Config()
11
8
  logger = set_logger(get_module_name(__file__))
12
9
 
10
+ from pymodaq_utils.warnings import deprecation_msg
11
+
12
+ deprecation_msg('Importing get_splash_sc stuff from pymodaq is deprecated '
13
+ 'in pymodaq>5.0.0,'
14
+ 'please use the same method from the '
15
+ 'pymodaq_gui.utils.splash module')
13
16
 
14
- def get_splash_sc():
15
- here = Path(__file__)
16
- splash_sc = QtWidgets.QSplashScreen(
17
- QtGui.QPixmap(str(here.parent.parent.parent.joinpath('splash.png'))),
18
- Qt.WindowStaysOnTopHint)
19
- return splash_sc
20
17
 
21
18
 
@@ -0,0 +1,8 @@
1
+ from pymodaq_gui.utils.widgets.lcd import LCD
2
+
3
+ from pymodaq_utils.warnings import deprecation_msg
4
+
5
+ deprecation_msg('Importing LCD from pymodaq is deprecated '
6
+ 'in pymodaq>5.0.0,'
7
+ 'please use the same method from the '
8
+ 'pymodaq_gui.utils.widgets.lcd module')