pymodaq 5.0.0__py3-none-any.whl → 5.0.2__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 (63) hide show
  1. pymodaq/__init__.py +55 -89
  2. pymodaq/control_modules/daq_move.py +129 -55
  3. pymodaq/control_modules/daq_move_ui.py +42 -11
  4. pymodaq/control_modules/daq_viewer.py +32 -13
  5. pymodaq/control_modules/move_utility_classes.py +346 -79
  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 +28 -8
  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 +49 -41
  21. pymodaq/extensions/pid/utils.py +7 -31
  22. pymodaq/extensions/utils.py +41 -7
  23. pymodaq/post_treatment/load_and_plot.py +43 -10
  24. pymodaq/resources/setup_plugin.py +1 -0
  25. pymodaq/updater.py +107 -0
  26. pymodaq/utils/chrono_timer.py +6 -7
  27. pymodaq/utils/daq_utils.py +6 -3
  28. pymodaq/utils/data.py +21 -17
  29. pymodaq/utils/enums.py +6 -0
  30. pymodaq/utils/gui_utils/loader_utils.py +29 -2
  31. pymodaq/utils/gui_utils/utils.py +9 -12
  32. pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
  33. pymodaq/utils/h5modules/module_saving.py +5 -2
  34. pymodaq/utils/leco/daq_move_LECODirector.py +22 -16
  35. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +15 -9
  36. pymodaq/utils/leco/leco_director.py +4 -3
  37. pymodaq/utils/leco/pymodaq_listener.py +9 -13
  38. pymodaq/utils/leco/utils.py +40 -7
  39. pymodaq/utils/managers/modules_manager.py +22 -12
  40. pymodaq/utils/managers/overshoot_manager.py +45 -1
  41. pymodaq/utils/managers/preset_manager.py +22 -46
  42. pymodaq/utils/managers/preset_manager_utils.py +17 -13
  43. pymodaq/utils/managers/remote_manager.py +1 -1
  44. pymodaq/utils/messenger.py +6 -0
  45. pymodaq/utils/parameter/__init__.py +5 -1
  46. pymodaq/utils/tcp_ip/mysocket.py +4 -110
  47. pymodaq/utils/tcp_ip/serializer.py +4 -769
  48. pymodaq/utils/tcp_ip/tcp_server_client.py +5 -5
  49. pymodaq-5.0.2.dist-info/METADATA +242 -0
  50. {pymodaq-5.0.0.dist-info → pymodaq-5.0.2.dist-info}/RECORD +54 -55
  51. {pymodaq-5.0.0.dist-info → pymodaq-5.0.2.dist-info}/WHEEL +1 -1
  52. {pymodaq-5.0.0.dist-info → pymodaq-5.0.2.dist-info}/entry_points.txt +1 -0
  53. pymodaq/examples/custom_app.py +0 -255
  54. pymodaq/examples/custom_viewer.py +0 -112
  55. pymodaq/examples/parameter_ex.py +0 -158
  56. pymodaq/examples/preset_MockCamera.xml +0 -1
  57. pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py +0 -142
  58. pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui +0 -232
  59. pymodaq/post_treatment/daq_measurement/daq_measurement_main.py +0 -391
  60. pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -2
  61. pymodaq-5.0.0.dist-info/METADATA +0 -166
  62. /pymodaq/{post_treatment/daq_measurement → daq_utils}/__init__.py +0 -0
  63. {pymodaq-5.0.0.dist-info → pymodaq-5.0.2.dist-info}/licenses/LICENSE +0 -0
@@ -118,6 +118,8 @@ class OvershootManager:
118
118
  self.det_modules = det_modules
119
119
  self.actuators_modules = actuators_modules
120
120
 
121
+ self._activated = False
122
+
121
123
  if msgbox:
122
124
  msgBox = QtWidgets.QMessageBox()
123
125
  msgBox.setText("Overshoot Manager?")
@@ -138,12 +140,21 @@ class OvershootManager:
138
140
  else: # cancel
139
141
  pass
140
142
 
143
+ @property
144
+ def activated(self) -> bool:
145
+ return self._activated
146
+
147
+ @activated.setter
148
+ def activated(self, status: bool):
149
+ self._activated = status
150
+
141
151
  def set_file_overshoot(self, filename, show=True):
142
152
  """
143
153
 
144
154
  """
145
155
  children = ioxml.XML_file_to_parameter(filename)
146
- self.overshoot_params = Parameter.create(title='Overshoot', name='Overshoot', type='group', children=children)
156
+ self.overshoot_params = Parameter.create(title='Overshoot', name='Overshoot', type='group',
157
+ children=children)
147
158
  if show:
148
159
  self.show_overshoot()
149
160
 
@@ -189,6 +200,39 @@ class OvershootManager:
189
200
  ioxml.parameter_to_xml_file(
190
201
  self.overshoot_params, os.path.join(overshoot_path, self.overshoot_params.child('filename').value()))
191
202
 
203
+ def activate_overshoot(self, det_modules, act_modules, status: bool):
204
+ det_titles = [det.title for det in det_modules]
205
+ move_titles = [move.title for move in act_modules]
206
+
207
+ if self.overshoot_params is not None:
208
+ for det_param in self.overshoot_params.child(
209
+ 'Detectors').children():
210
+ if det_param['trig_overshoot']:
211
+ det_index = det_titles.index(det_param.opts['title'])
212
+ det_module = det_modules[det_index]
213
+ det_module.settings.child(
214
+ 'main_settings', 'overshoot', 'stop_overshoot').setValue(status)
215
+ det_module.settings.child(
216
+ 'main_settings', 'overshoot', 'overshoot_value').setValue(
217
+ det_param['overshoot_value'])
218
+ for move_param in det_param.child('params').children():
219
+ if move_param['move_overshoot']:
220
+ move_index = move_titles.index(move_param.opts['title'])
221
+ move_module = act_modules[move_index]
222
+ if status:
223
+ det_module.overshoot_signal.connect(
224
+ self.create_overshoot_fun(
225
+ move_module, move_param['position']))
226
+ else:
227
+ try:
228
+ det_module.overshoot_signal.disconnect()
229
+ except Exception as e:
230
+ pass
231
+
232
+ @staticmethod
233
+ def create_overshoot_fun(move_module, position):
234
+ return lambda: move_module.move_abs(position)
235
+
192
236
 
193
237
  if __name__ == '__main__':
194
238
  app = QtWidgets.QApplication(sys.argv)
@@ -19,13 +19,10 @@ import pymodaq.utils.managers.preset_manager_utils # to register move and det t
19
19
  logger = set_logger(get_module_name(__file__))
20
20
 
21
21
  # check if preset_mode directory exists on the drive
22
- pid_path = config_mod_pymodaq.get_set_pid_path()
23
22
  preset_path = config_mod_pymodaq.get_set_preset_path()
24
23
  overshoot_path = config_mod_pymodaq.get_set_overshoot_path()
25
24
  layout_path = config_mod_pymodaq.get_set_layout_path()
26
25
 
27
- pid_models = [mod['name'] for mod in get_models()]
28
-
29
26
 
30
27
  class PresetManager:
31
28
  def __init__(self, msgbox=False, path=None, extra_params=[], param_options=[]):
@@ -38,8 +35,8 @@ class PresetManager:
38
35
  self.extra_params = extra_params
39
36
  self.param_options = param_options
40
37
  self.preset_path = path
41
- self.preset_params = None
42
- self.pid_type = False
38
+ self.preset_params: Parameter = None
39
+
43
40
  if msgbox:
44
41
  msgBox = QtWidgets.QMessageBox()
45
42
  msgBox.setText("Preset Manager?")
@@ -60,33 +57,28 @@ class PresetManager:
60
57
  else: # cancel
61
58
  pass
62
59
 
60
+ @property
61
+ def filename(self) -> str:
62
+ try:
63
+ return self.preset_params['filename']
64
+ except:
65
+ return None
66
+
63
67
  def set_file_preset(self, filename, show=True):
64
68
  """
65
69
 
66
70
  """
67
71
  status = False
68
- self.pid_type = False
69
72
  children = ioxml.XML_file_to_parameter(filename)
70
73
  self.preset_params = Parameter.create(title='Preset', name='Preset', type='group', children=children)
71
74
  if show:
72
75
  status = self.show_preset()
73
76
  return status
74
77
 
75
- def get_set_pid_model_params(self, model_file):
76
- self.preset_params.child('model_settings').clearChildren()
77
- model = get_models(model_file)
78
- if model is not None:
79
- params = model['class'].params
80
- self.preset_params.child('model_settings').addChildren(params)
81
78
 
82
79
  def set_new_preset(self):
83
- self.pid_type = False
84
80
  param = [
85
81
  {'title': 'Filename:', 'name': 'filename', 'type': 'str', 'value': 'preset_default'},
86
- {'title': 'Use PID as actuator:', 'name': 'use_pid', 'type': 'bool', 'value': False},
87
- # {'title': 'Saving options:', 'name': 'saving_options', 'type': 'group', 'children': H5Saver.params},
88
- {'title': 'PID models:', 'name': 'pid_models', 'type': 'list', 'visible': False,
89
- 'limits': pid_models},
90
82
  {'title': 'Model Settings:', 'name': 'model_settings', 'type': 'group', 'visible': False, 'children': []},
91
83
  ]
92
84
  params_move = [
@@ -102,9 +94,6 @@ class PresetManager:
102
94
  except Exception as e:
103
95
  logger.exception(str(e))
104
96
 
105
- if len(pid_models) != 0:
106
- self.get_set_pid_model_params(pid_models[0])
107
-
108
97
  self.preset_params.sigTreeStateChanged.connect(self.parameter_tree_changed)
109
98
 
110
99
  status = self.show_preset()
@@ -129,12 +118,6 @@ class PresetManager:
129
118
  data[0].child('params', 'main_settings', 'module_name').setValue(data[0].child('name').value())
130
119
 
131
120
  elif change == 'value':
132
-
133
- if param.name() == 'use_pid':
134
- self.preset_params.child('pid_models').show(param.value())
135
- self.preset_params.child('model_settings').show(param.value())
136
- if param.name() == 'pid_models' and param.value() != '':
137
- self.get_set_pid_model_params(param.value())
138
121
  if param.name() == 'name':
139
122
  param.parent().child('params', 'main_settings', 'module_name').setValue(param.value())
140
123
 
@@ -148,8 +131,8 @@ class PresetManager:
148
131
  dialog = QtWidgets.QDialog()
149
132
  vlayout = QtWidgets.QVBoxLayout()
150
133
  tree = ParameterTree()
151
- tree.setMinimumWidth(400)
152
- tree.setMinimumHeight(500)
134
+ # tree.setMinimumWidth(400)
135
+ # tree.setMinimumHeight(500)
153
136
  tree.setParameters(self.preset_params, showTop=False)
154
137
 
155
138
  vlayout.addWidget(tree)
@@ -165,20 +148,18 @@ class PresetManager:
165
148
  dialog.setWindowTitle('Fill in information about this manager')
166
149
  res = dialog.exec()
167
150
 
168
- if self.pid_type:
169
- path = pid_path
170
- else:
171
- path = self.preset_path
151
+ path = self.preset_path
152
+ file= None
172
153
 
173
154
  if res == dialog.Accepted:
174
155
  # save managers parameters in a xml file
175
156
  # start = os.path.split(os.path.split(os.path.realpath(__file__))[0])[0]
176
157
  # start = os.path.join("..",'daq_scan')
177
- filename_without_extension = self.preset_params.child('filename').value()
158
+ filename_without_extension = self.filename
178
159
 
179
160
  try:
180
161
  ioxml.parameter_to_xml_file(self.preset_params,
181
- os.path.join(path, filename_without_extension),
162
+ path.joinpath(filename_without_extension),
182
163
  overwrite=False)
183
164
  except FileExistsError as currenterror:
184
165
  # logger.warning(str(currenterror)+"File " + filename_without_extension + ".xml exists")
@@ -187,24 +168,19 @@ class PresetManager:
187
168
  message="File exist do you want to overwrite it ?")
188
169
  if user_agreed:
189
170
  ioxml.parameter_to_xml_file(self.preset_params,
190
- os.path.join(path, filename_without_extension))
171
+ path.joinpath(filename_without_extension))
191
172
  logger.warning(f"File {filename_without_extension}.xml overwriten at user request")
192
173
  else:
193
174
  logger.warning(f"File {filename_without_extension}.xml wasn't saved at user request")
194
175
  # emit status signal to dashboard to write : did not save ?
195
176
  pass
196
177
 
197
- if not self.pid_type:
198
- # check if overshoot configuration and layout configuration with same name exists => delete them if yes
199
- file = os.path.splitext(self.preset_params.child('filename').value())[0]
200
- file = os.path.join(overshoot_path, file + '.xml')
201
- if os.path.isfile(file):
202
- os.remove(file)
203
-
204
- file = os.path.splitext(self.preset_params.child('filename').value())[0]
205
- file = os.path.join(layout_path, file + '.dock')
206
- if os.path.isfile(file):
207
- os.remove(file)
178
+ # check if overshoot configuration and layout configuration with same name exists => delete them if yes
179
+ over_shoot_file = overshoot_path.joinpath(self.filename + '.xml')
180
+ over_shoot_file.unlink(missing_ok=True)
181
+
182
+ layout_file = layout_path.joinpath(self.filename + '.dock')
183
+ layout_file.unlink(missing_ok=True)
208
184
 
209
185
  return res == dialog.Accepted
210
186
 
@@ -4,6 +4,7 @@ from pymodaq_utils.logger import set_logger, get_module_name
4
4
  from pymodaq_utils import utils
5
5
 
6
6
  from pymodaq_gui.parameter.pymodaq_ptypes import registerParameterType, GroupParameter
7
+ from pymodaq_gui.parameter.utils import get_param_dict_from_name
7
8
 
8
9
  from pymodaq.control_modules.move_utility_classes import params as daq_move_params
9
10
  from pymodaq.control_modules.viewer_utility_classes import params as daq_viewer_params
@@ -76,20 +77,23 @@ class PresetScalableGroupMove(GroupParameter):
76
77
  for main_child in params:
77
78
  if main_child['name'] == 'move_settings':
78
79
  main_child['children'] = params_hardware
80
+ controller_dict = get_param_dict_from_name(params_hardware, 'controller_ID')
81
+ controller_dict['value'] = random.randint(0, 9999)
82
+
79
83
  elif main_child['name'] == 'main_settings':
80
- for child in main_child['children']:
81
- if child['name'] == 'move_type':
82
- child['value'] = typ
83
- if child['name'] == 'controller_ID':
84
- child['value'] = random.randint(0, 9999)
84
+ typ_dict = get_param_dict_from_name(main_child['children'], 'move_type')
85
+ typ_dict['value'] = typ
85
86
 
86
- child = {'title': 'Actuator {:02.0f}'.format(newindex), 'name': f'{name_prefix}{newindex:02.0f}',
87
+ child = {'title': 'Actuator {:02.0f}'.format(newindex),
88
+ 'name': f'{name_prefix}{newindex:02.0f}',
87
89
  'type': 'group',
88
- 'removable': True, 'children': [
89
- {'title': 'Name:', 'name': 'name', 'type': 'str', 'value': 'Move {:02.0f}'.format(newindex)},
90
- {'title': 'Init?:', 'name': 'init', 'type': 'bool', 'value': True},
91
- {'title': 'Settings:', 'name': 'params', 'type': 'group', 'children': params
92
- }], 'removable': True, 'renamable': False}
90
+ 'removable': True, 'renamable': False,
91
+ 'children': [
92
+ {'title': 'Name:', 'name': 'name', 'type': 'str',
93
+ 'value': 'Move {:02.0f}'.format(newindex)},
94
+ {'title': 'Init?:', 'name': 'init', 'type': 'bool', 'value': True},
95
+ {'title': 'Settings:', 'name': 'params', 'type': 'group', 'children': params},
96
+ ]}
93
97
 
94
98
  self.addChild(child)
95
99
 
@@ -155,8 +159,6 @@ class PresetScalableGroupDet(GroupParameter):
155
159
  child['value'] = typ[6:]
156
160
  if child['name'] == 'controller_status':
157
161
  child['visible'] = True
158
- if child['name'] == 'controller_ID':
159
- child['value'] = random.randint(0, 9999)
160
162
 
161
163
  if '0D' in typ:
162
164
  parent_module = utils.find_dict_in_list_from_key_val(DAQ_0DViewer_Det_types, 'name', typ[6:])
@@ -186,6 +188,8 @@ class PresetScalableGroupDet(GroupParameter):
186
188
  main_child['children'].remove(child)
187
189
 
188
190
  main_child['children'].extend(params_hardware)
191
+ controller_dict = get_param_dict_from_name(main_child['children'], 'controller_ID')
192
+ controller_dict['value'] = random.randint(0, 9999)
189
193
 
190
194
  child = {'title': 'Det {:02.0f}'.format(newindex), 'name': f'{name_prefix}{newindex:02.0f}',
191
195
  'type': 'group', 'children': [
@@ -17,7 +17,7 @@ logger = set_logger(get_module_name(__file__))
17
17
  remote_path = get_set_remote_path()
18
18
  remote_types = ['ShortCut', 'Joystick']
19
19
 
20
- actuator_actions = ['move_Rel', 'move_Rel_p', 'move_Rel_m']
20
+ actuator_actions = ['move_rel', 'move_rel_p', 'move_rel_m']
21
21
  detector_actions = ['snap', 'grab', 'stop']
22
22
  remote_types = ['Keyboard', 'Joystick']
23
23
 
@@ -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')
@@ -1,6 +1,10 @@
1
1
  from pymodaq_gui.parameter import Parameter, ParameterTree, utils, ioxml, pymodaq_ptypes
2
-
2
+ from sys import modules as sysmodules
3
3
  from pymodaq_utils.warnings import deprecation_msg
4
4
 
5
+
6
+ sysmodules["pymodaq.utils.parameter.pymodaq_ptypes"] = pymodaq_ptypes
7
+
8
+
5
9
  deprecation_msg('Importing Parameter stuff from pymodaq is deprecated in pymodaq>5.0.0,'
6
10
  'please use the pymodaq_gui package')
@@ -4,115 +4,9 @@ Created the 26/10/2023
4
4
 
5
5
  @author: Sebastien Weber
6
6
  """
7
- import socket
8
- from typing import Union
7
+ from pymodaq_data.serialize.mysocket import Socket
9
8
 
10
- from pymodaq.utils.tcp_ip.serializer import Serializer
11
-
12
-
13
- class Socket:
14
- """Custom Socket wrapping the built-in one and added functionalities to
15
- make sure message have been sent and received entirely"""
16
- def __init__(self, socket: socket.socket = None):
17
- super().__init__()
18
- self._socket = socket
19
-
20
- def __eq__(self, other_obj):
21
- if isinstance(other_obj, Socket):
22
- other_obj = other_obj.socket
23
- return self.socket == other_obj
24
-
25
- @property
26
- def socket(self):
27
- return self._socket
28
-
29
- def bind(self, *args, **kwargs):
30
- return self.socket.bind(*args, **kwargs)
31
-
32
- def listen(self, *args, **kwargs):
33
- return self.socket.listen(*args, **kwargs)
34
-
35
- def getsockname(self, *args, **kwargs):
36
- return self.socket.getsockname(*args, **kwargs)
37
-
38
- def accept(self):
39
- sock, addr = self.socket.accept()
40
- return Socket(sock), addr
41
-
42
- def connect(self, *args, **kwargs):
43
- return self.socket.connect(*args, **kwargs)
44
-
45
- def send(self, *args, **kwargs):
46
- return self.socket.send(*args, **kwargs)
47
-
48
- def sendall(self, *args, **kwargs):
49
- return self.socket.sendall(*args, **kwargs)
50
-
51
- def recv(self, *args, **kwargs):
52
- return self.socket.recv(*args, **kwargs)
53
-
54
- def close(self):
55
- return self.socket.close()
56
-
57
- def check_sended(self, data_bytes: bytes):
58
- """
59
- Make sure all bytes are sent through the socket
60
- Parameters
61
- ----------
62
- data_bytes: bytes
63
- """
64
- if not isinstance(data_bytes, bytes):
65
- raise TypeError(f'{data_bytes} should be an bytes string, not a {type(data_bytes)}')
66
- sended = 0
67
- while sended < len(data_bytes):
68
- sended += self.socket.send(data_bytes[sended:])
69
-
70
- def check_sended_with_serializer(self, obj: object):
71
- """ Convenience function to convert permitted objects to bytes and then use the check_sended method
72
-
73
- For a list of allowed objects, see :meth:`Serializer.to_bytes`
74
- """
75
- self.check_sended(Serializer(obj).to_bytes())
76
-
77
- def check_received_length(self, length) -> bytes:
78
- """
79
- Make sure all bytes (length) that should be received are received through the socket
80
-
81
- Parameters
82
- ----------
83
- length: int
84
- The number of bytes to be read from the socket
85
-
86
- Returns
87
- -------
88
- bytes
89
- """
90
- if not isinstance(length, int):
91
- raise TypeError(f'{length} should be an integer, not a {type(length)}')
92
-
93
- mess_length = 0
94
- data_bytes = b''
95
- while mess_length < length:
96
- if mess_length < length - 4096:
97
- data_bytes_tmp = self.socket.recv(4096)
98
- else:
99
- data_bytes_tmp = self.socket.recv(length - mess_length)
100
- mess_length += len(data_bytes_tmp)
101
- data_bytes += data_bytes_tmp
102
- # print(data_bytes)
103
- return data_bytes
104
-
105
- def get_first_nbytes(self, length: int) -> bytes:
106
- """ Read the first N bytes from the socket
107
-
108
- Parameters
109
- ----------
110
- length: int
111
- The number of bytes to be read from the socket
112
-
113
- Returns
114
- -------
115
- bytes: the read bytes string
116
- """
117
- return self.check_received_length(length)
9
+ from pymodaq_utils.utils import deprecation_msg
118
10
 
11
+ deprecation_msg('Importing Socket from pymodaq is deprecated in PyMoDAQ >= 5,'
12
+ 'import it from pymodaq_data.serialize.mysocket')