pymodaq 5.0.18__py3-none-any.whl → 5.1.0__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 (92) hide show
  1. pymodaq/__init__.py +23 -11
  2. pymodaq/control_modules/__init__.py +1 -0
  3. pymodaq/control_modules/daq_move.py +451 -246
  4. pymodaq/control_modules/daq_move_ui/__init__.py +0 -0
  5. pymodaq/control_modules/daq_move_ui/factory.py +48 -0
  6. pymodaq/control_modules/{daq_move_ui.py → daq_move_ui/ui_base.py} +168 -210
  7. pymodaq/control_modules/daq_move_ui/uis/__init__.py +0 -0
  8. pymodaq/control_modules/daq_move_ui/uis/binary.py +139 -0
  9. pymodaq/control_modules/daq_move_ui/uis/original.py +120 -0
  10. pymodaq/control_modules/daq_move_ui/uis/relative.py +124 -0
  11. pymodaq/control_modules/daq_move_ui/uis/simple.py +126 -0
  12. pymodaq/control_modules/daq_viewer.py +113 -101
  13. pymodaq/control_modules/daq_viewer_ui.py +41 -31
  14. pymodaq/control_modules/mocks.py +2 -2
  15. pymodaq/control_modules/move_utility_classes.py +113 -41
  16. pymodaq/control_modules/thread_commands.py +137 -0
  17. pymodaq/control_modules/ui_utils.py +72 -0
  18. pymodaq/control_modules/utils.py +107 -63
  19. pymodaq/control_modules/viewer_utility_classes.py +13 -17
  20. pymodaq/dashboard.py +1294 -625
  21. pymodaq/examples/qt_less_standalone_module.py +48 -11
  22. pymodaq/extensions/__init__.py +8 -3
  23. pymodaq/extensions/adaptive/__init__.py +2 -0
  24. pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
  25. pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
  26. pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
  27. pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
  28. pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
  29. pymodaq/extensions/adaptive/utils.py +123 -0
  30. pymodaq/extensions/bayesian/__init__.py +1 -1
  31. pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
  32. pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
  33. pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
  34. pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
  35. pymodaq/extensions/bayesian/utils.py +71 -297
  36. pymodaq/extensions/daq_logger/daq_logger.py +7 -12
  37. pymodaq/extensions/daq_logger/h5logging.py +1 -1
  38. pymodaq/extensions/daq_scan.py +30 -55
  39. pymodaq/extensions/data_mixer/__init__.py +0 -0
  40. pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
  41. pymodaq/extensions/data_mixer/data_mixer.py +262 -0
  42. pymodaq/extensions/data_mixer/model.py +108 -0
  43. pymodaq/extensions/data_mixer/models/__init__.py +0 -0
  44. pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
  45. pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
  46. pymodaq/extensions/data_mixer/parser.py +53 -0
  47. pymodaq/extensions/data_mixer/utils.py +23 -0
  48. pymodaq/extensions/h5browser.py +3 -34
  49. pymodaq/extensions/optimizers_base/__init__.py +0 -0
  50. pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
  51. pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
  52. pymodaq/extensions/optimizers_base/utils.py +427 -0
  53. pymodaq/extensions/pid/actuator_controller.py +3 -2
  54. pymodaq/extensions/pid/daq_move_PID.py +107 -30
  55. pymodaq/extensions/pid/pid_controller.py +613 -287
  56. pymodaq/extensions/pid/utils.py +8 -5
  57. pymodaq/extensions/utils.py +17 -2
  58. pymodaq/resources/config_template.toml +57 -0
  59. pymodaq/resources/preset_default.xml +1 -1
  60. pymodaq/utils/config.py +10 -4
  61. pymodaq/utils/daq_utils.py +14 -0
  62. pymodaq/utils/data.py +1 -0
  63. pymodaq/utils/gui_utils/loader_utils.py +25 -15
  64. pymodaq/utils/h5modules/module_saving.py +134 -22
  65. pymodaq/utils/leco/daq_move_LECODirector.py +123 -84
  66. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +84 -97
  67. pymodaq/utils/leco/director_utils.py +32 -16
  68. pymodaq/utils/leco/leco_director.py +104 -27
  69. pymodaq/utils/leco/pymodaq_listener.py +186 -97
  70. pymodaq/utils/leco/rpc_method_definitions.py +43 -0
  71. pymodaq/utils/leco/utils.py +25 -25
  72. pymodaq/utils/managers/batchscan_manager.py +12 -11
  73. pymodaq/utils/managers/modules_manager.py +74 -33
  74. pymodaq/utils/managers/overshoot_manager.py +11 -10
  75. pymodaq/utils/managers/preset_manager.py +100 -64
  76. pymodaq/utils/managers/preset_manager_utils.py +163 -107
  77. pymodaq/utils/managers/remote_manager.py +21 -16
  78. pymodaq/utils/scanner/scan_factory.py +12 -3
  79. pymodaq/utils/scanner/scan_selector.py +1 -3
  80. pymodaq/utils/scanner/scanner.py +35 -6
  81. pymodaq/utils/scanner/scanners/_1d_scanners.py +15 -46
  82. pymodaq/utils/scanner/scanners/_2d_scanners.py +21 -68
  83. pymodaq/utils/scanner/scanners/sequential.py +50 -31
  84. pymodaq/utils/scanner/scanners/tabular.py +45 -28
  85. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/METADATA +7 -6
  86. pymodaq-5.1.0.dist-info/RECORD +154 -0
  87. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/entry_points.txt +0 -2
  88. pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -690
  89. pymodaq/utils/leco/desktop.ini +0 -2
  90. pymodaq-5.0.18.dist-info/RECORD +0 -121
  91. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/WHEEL +0 -0
  92. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -32,8 +32,8 @@ class Scan2DBase(ScannerBase):
32
32
  ]
33
33
  axes = ('axis1','axis2')
34
34
  n_axes = 2
35
- def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
36
- super().__init__(actuators=actuators)
35
+ def __init__(self, actuators: List['DAQ_Move'] = None, display_units=True, **_ignored):
36
+ super().__init__(actuators=actuators, display_units=display_units)
37
37
  self.axes_unique = []
38
38
 
39
39
 
@@ -64,8 +64,19 @@ class Scan2DLinear(Scan2DBase):
64
64
  scan_type = 'Scan2D'
65
65
  scan_subtype = 'Linear'
66
66
 
67
- def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
68
- super().__init__(actuators=actuators)
67
+ def __init__(self, actuators: List['DAQ_Move'] = None, display_units=True, **_ignored):
68
+ super().__init__(actuators=actuators, display_units=display_units)
69
+
70
+ def set_units(self):
71
+ """ Update settings units depending on the scanner type and the display_units boolean"""
72
+ if len(self.actuators) > 0:
73
+ for child in self.settings.child('axis1').children():
74
+ child.setOpts(
75
+ suffix='' if not self.display_units else self.actuators[0].units)
76
+ if len(self.actuators) > 1:
77
+ for child in self.settings.child('axis2').children():
78
+ child.setOpts(
79
+ suffix='' if not self.display_units else self.actuators[1].units)
69
80
 
70
81
  def get_pos(self):
71
82
  starts = np.array([self.settings[ax, f'start_{ax}'] for ax in self.axes])
@@ -133,8 +144,8 @@ class Scan2DLinear(Scan2DBase):
133
144
  class Scan2DLinearBF(Scan2DLinear):
134
145
  scan_subtype = 'LinearBackForce'
135
146
 
136
- def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
137
- super().__init__(actuators=actuators)
147
+ def __init__(self, actuators: List['DAQ_Move'] = None, display_units=True, **_ignored):
148
+ super().__init__(actuators=actuators, display_units=display_units)
138
149
 
139
150
  def set_scan(self):
140
151
  starts, stops, steps = self.get_pos()
@@ -163,8 +174,8 @@ class Scan2DLinearBF(Scan2DLinear):
163
174
  class Scan2DRandom(Scan2DLinear):
164
175
  scan_subtype = 'Random'
165
176
 
166
- def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
167
- super().__init__(actuators=actuators)
177
+ def __init__(self, actuators: List['DAQ_Move'] = None, display_units=True, **_ignored):
178
+ super().__init__(actuators=actuators, display_units=display_units)
168
179
 
169
180
  def set_scan(self):
170
181
  super().set_scan()
@@ -197,8 +208,8 @@ class Scan2DSpiral(Scan2DLinear):
197
208
  ]},
198
209
  ]
199
210
 
200
- def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
201
- super().__init__(actuators=actuators)
211
+ def __init__(self, actuators: List['DAQ_Move'] = None, display_units=True, **_ignored):
212
+ super().__init__(actuators=actuators, display_units=display_units)
202
213
 
203
214
  def set_settings_titles(self):
204
215
  if len(self.actuators) == 2:
@@ -286,61 +297,3 @@ class Scan2DSpiral(Scan2DLinear):
286
297
  self.settings.child(ax, f'rmax_{ax}').setValue(
287
298
  (coordinates[0, i] - coordinates[1, i]) / 2)
288
299
 
289
-
290
- try:
291
- import adaptive
292
-
293
- @ScannerFactory.register()
294
- class Scan2DAdaptive(Scan2DLinear):
295
- scan_subtype = 'Adaptive'
296
-
297
- params = [
298
- {'title': 'Loss type', 'name': 'scan_loss', 'type': 'list',
299
- 'limits': ['default', 'curvature', 'uniform'],
300
- 'tip': 'Type of loss used by the algo. to determine next points'},
301
-
302
- {'title': 'Ax1:', 'name': 'axis1', 'type': 'group',
303
- 'children':[
304
- {'title': 'Start Ax1:', 'name': 'start_axis1', 'type': 'float',
305
- 'value': config('scan', 'scan2D', 'linear', 'start1')},
306
- {'title': 'Stop Ax1:', 'name': 'stop_axis1', 'type': 'float',
307
- 'value': config('scan', 'scan2D', 'linear', 'stop1')},
308
- {'title': 'Step Ax1:', 'name': 'step_axis1', 'type': 'float',
309
- 'value': config('scan', 'scan2D', 'linear', 'step1')},
310
- ]},
311
- {'title': 'Ax2:', 'name': 'axis2', 'type': 'group',
312
- 'children':[
313
- {'title': 'Start Ax2:', 'name': 'start_axis2', 'type': 'float',
314
- 'value': config('scan', 'scan2D', 'linear', 'start2')},
315
- {'title': 'Stop Ax2:', 'name': 'stop_axis2', 'type': 'float',
316
- 'value': config('scan', 'scan2D', 'linear', 'stop2')},
317
- {'title': 'Step Ax2:', 'name': 'step_axis2', 'type': 'float',
318
- 'value': config('scan', 'scan2D', 'linear', 'step2')},
319
- ]},
320
- ]
321
- distribution = DataDistribution['spread']
322
-
323
- def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
324
- super().__init__(actuators=actuators)
325
-
326
- def set_scan(self):
327
-
328
- self.axes_unique = [np.array([]), np.array([])]
329
- self.axes_indexes = np.array([], dtype=int)
330
- self.positions = np.zeros((0, 2))
331
-
332
- def evaluate_steps(self) -> int:
333
- return 1
334
-
335
- def get_nav_axes(self) -> List[Axis]:
336
- return [Axis(label=f'{act.mod_name} axis',
337
- units=f'{act.units}',
338
- data=self.positions[:, ind],
339
- index=ind) for ind, act in enumerate(self.actuators)]
340
-
341
- def get_scan_shape(self) -> Tuple[int]:
342
- return () # unknown shape
343
-
344
- except ModuleNotFoundError:
345
- logger.info('adaptive module is not present, no adaptive scan possible')
346
-
@@ -4,7 +4,7 @@ Created the 05/12/2022
4
4
 
5
5
  @author: Sebastien Weber
6
6
  """
7
- from typing import List, Tuple, TYPE_CHECKING
7
+ from typing import List, Tuple, TYPE_CHECKING, Iterable
8
8
 
9
9
  import numpy as np
10
10
 
@@ -13,6 +13,8 @@ from pymodaq_data.data import Axis, DataDistribution
13
13
  from pymodaq_utils.logger import set_logger, get_module_name
14
14
  from pymodaq_utils import math_utils as mutils
15
15
  from pymodaq_utils import config as configmod
16
+ from pymodaq_data import Q_
17
+
16
18
  from pymodaq_gui import utils as gutils
17
19
  from ..scan_factory import ScannerFactory, ScannerBase, ScanParameterManager
18
20
  from pymodaq_gui.parameter import utils as putils
@@ -36,7 +38,7 @@ class TableModelSequential(gutils.TableModel):
36
38
  editable = [False, True, True, True]
37
39
  if 'editable' in kwargs:
38
40
  editable = kwargs.pop('editable')
39
- super().__init__(data, header, editable=editable, **kwargs)
41
+ super().__init__(data, header, editable=editable, cast=str, **kwargs)
40
42
 
41
43
  def __repr__(self):
42
44
  return f'{self.__class__.__name__} from module {self.__class__.__module__}'
@@ -54,9 +56,10 @@ class TableModelSequential(gutils.TableModel):
54
56
  -------
55
57
  bool: True is the new value is fine (change some other values if needed) otherwise False
56
58
  """
57
- start = self.data(self.index(row, 1), QtCore.Qt.DisplayRole)
58
- stop = self.data(self.index(row, 2), QtCore.Qt.DisplayRole)
59
- step = self.data(self.index(row, 3), QtCore.Qt.DisplayRole)
59
+ start = Q_(self.data(self.index(row, 1), QtCore.Qt.DisplayRole))
60
+ stop = Q_(self.data(self.index(row, 2), QtCore.Qt.DisplayRole))
61
+ step = Q_(self.data(self.index(row, 3), QtCore.Qt.DisplayRole))
62
+ value = Q_(value)
60
63
  isstep = False
61
64
  if col == 1: # the start
62
65
  start = value
@@ -65,14 +68,16 @@ class TableModelSequential(gutils.TableModel):
65
68
  elif col == 3: # the step
66
69
  isstep = True
67
70
  step = value
68
-
69
- if np.abs(step) < 1e-12 or start == stop:
71
+ try:
72
+ if np.abs(step).magnitude < 1e-12 or start == stop:
73
+ return False
74
+ if np.sign(stop - start) != np.sign(step):
75
+ if isstep:
76
+ self._data[row][2] = str(-stop)
77
+ else:
78
+ self._data[row][3] = str(-step)
79
+ except (TypeError, ValueError):
70
80
  return False
71
- if np.sign(stop - start) != np.sign(step):
72
- if isstep:
73
- self._data[row][2] = -stop
74
- else:
75
- self._data[row][3] = -step
76
81
  return True
77
82
 
78
83
 
@@ -88,13 +93,17 @@ class SequentialScanner(ScannerBase):
88
93
  distribution = DataDistribution['uniform']
89
94
  n_axes = 1
90
95
 
91
- def __init__(self, actuators: List['DAQ_Move']):
96
+ def __init__(self, actuators: List['DAQ_Move'], display_units=True, **_ignored):
92
97
 
93
98
  self.table_model: TableModelSequential = None
94
99
  self.table_view: TableViewCustom = None
95
- super().__init__(actuators)
100
+ super().__init__(actuators, display_units=display_units)
101
+ self.delegates: Iterable[gutils.SpinBoxDelegate] = []
96
102
  self.update_model()
97
103
 
104
+ def set_units(self):
105
+ pass
106
+
98
107
  @property
99
108
  def actuators(self):
100
109
  return self._actuators
@@ -116,9 +125,15 @@ class SequentialScanner(ScannerBase):
116
125
  ind_row = names.index(act.title)
117
126
  init_data.append(self.table_model.get_data_all()[ind_row])
118
127
  else:
119
- init_data.append([act.title, 0., 1., 0.1])
128
+ if self.display_units:
129
+ init_data = [[act.title, f'0. {act.units}', f'1. {act.units}', f'0.1 {act.units}'] for act in self._actuators]
130
+ else:
131
+ init_data.append([act.title, '0.', '1.', '0.1'])
120
132
  else:
121
- init_data = [[act.title, 0., 1., 0.1] for act in self._actuators]
133
+ if self.display_units:
134
+ init_data = [[act.title, f'0. {act.units}', f'1. {act.units}', f'0.1 {act.units}'] for act in self._actuators]
135
+ else:
136
+ init_data = [[act.title, '0.', '1.', '0.1'] for act in self._actuators]
122
137
  self.table_model = TableModelSequential(init_data, )
123
138
  self.table_view = putils.get_widget_from_tree(self.settings_tree, TableViewCustom)[0]
124
139
  self.settings.child('seq_table').setValue(self.table_model)
@@ -126,19 +141,19 @@ class SequentialScanner(ScannerBase):
126
141
  self.update_table_view()
127
142
 
128
143
  def get_pos(self):
129
- starts = np.array([self.table_model.get_data(ind, 1)
130
- for ind in range(self.table_model.rowCount(None))])
131
- stops = np.array([self.table_model.get_data(ind, 2)
132
- for ind in range(self.table_model.rowCount(None))])
133
- steps = np.array([self.table_model.get_data(ind, 3)
134
- for ind in range(self.table_model.rowCount(None))])
144
+ starts = [Q_(self.table_model.get_data(ind, 1))
145
+ for ind in range(self.table_model.rowCount(None))]
146
+ stops = [Q_(self.table_model.get_data(ind, 2))
147
+ for ind in range(self.table_model.rowCount(None))]
148
+ steps = [Q_(self.table_model.get_data(ind, 3))
149
+ for ind in range(self.table_model.rowCount(None))]
135
150
  return starts, stops, steps
136
151
 
137
152
  def evaluate_steps(self) -> int:
138
153
  starts, stops, steps = self.get_pos()
139
154
  n_steps = 1
140
- for ind in range(starts.size):
141
- n_steps *= np.abs((stops[ind] - starts[ind]) / steps[ind]) + 1
155
+ for ind in range(len(starts)):
156
+ n_steps *= (np.abs((stops[ind] - starts[ind]) / steps[ind]) + 1).magnitude
142
157
  return int(n_steps)
143
158
 
144
159
  @staticmethod
@@ -152,13 +167,17 @@ class SequentialScanner(ScannerBase):
152
167
  return state
153
168
 
154
169
  def update_table_view(self):
155
- self.table_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
156
- self.table_view.horizontalHeader().setStretchLastSection(True)
170
+ self.table_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
171
+ #self.table_view.horizontalHeader().setStretchLastSection(True)
157
172
  self.table_view.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
158
173
  self.table_view.setSelectionMode(QtWidgets.QTableView.SingleSelection)
159
- styledItemDelegate = QtWidgets.QStyledItemDelegate()
160
- styledItemDelegate.setItemEditorFactory(gutils.SpinBoxDelegate())
161
- self.table_view.setItemDelegate(styledItemDelegate)
174
+ self.delegates = [] # ItemDelegates should have parents and be instance attribute to work with setItemDelegateForColumn
175
+ for ind_actuator, actuator in enumerate(self.actuators):
176
+
177
+ self.delegates.append(gutils.SpinBoxDelegate(self.table_view,
178
+ units=actuator.units if self.display_units else None))
179
+ self.table_view.setItemDelegateForRow(
180
+ ind_actuator, self.delegates[-1])
162
181
 
163
182
  self.table_view.setDragEnabled(True)
164
183
  self.table_view.setDropIndicatorShown(True)
@@ -186,8 +205,8 @@ class SequentialScanner(ScannerBase):
186
205
  state = self.pos_above_stops(positions, steps, stops)
187
206
  if not np.any(np.array(state)):
188
207
  all_positions.append(positions.copy())
189
-
190
- self.get_info_from_positions(np.array(all_positions))
208
+ all_positions = np.array([[elt.magnitude for elt in positions] for positions in all_positions])
209
+ self.get_info_from_positions(all_positions)
191
210
 
192
211
  def get_nav_axes(self) -> List[Axis]:
193
212
  return [Axis(label=f'{act.title}', units=act.units, data=self.axes_unique[ind], index=ind)
@@ -4,12 +4,14 @@ Created the 05/12/2022
4
4
 
5
5
  @author: Sebastien Weber
6
6
  """
7
- from typing import List, Tuple, TYPE_CHECKING
7
+ from typing import List, Tuple, TYPE_CHECKING, Iterable
8
8
 
9
9
  import numpy as np
10
10
 
11
11
  from qtpy import QtCore, QtWidgets
12
12
  from pymodaq_data.data import Axis, DataDistribution
13
+ from pymodaq_data import Q_
14
+ from pymodaq_gui.utils import SpinBoxDelegate
13
15
  from pymodaq_utils.logger import set_logger, get_module_name
14
16
 
15
17
  from pymodaq_utils import config as configmod
@@ -37,19 +39,18 @@ class TableModelTabular(gutils.TableModel):
37
39
  kwargs.pop('header')
38
40
  else:
39
41
  raise Exception('Invalid header')
40
-
41
42
  header = [name for name in axes_name]
42
43
  editable = [True for name in axes_name]
43
- super().__init__(data, header, editable=editable, **kwargs)
44
+ super().__init__(data, header, editable=editable, cast=str, **kwargs)
44
45
 
45
46
  def __len__(self):
46
47
  return len(self._data)
47
48
 
48
49
  def add_data(self, row, data=None):
49
50
  if data is not None:
50
- self.insert_data(row, [float(d) for d in data])
51
+ self.insert_data(row, [f'{d}' for d in data])
51
52
  else:
52
- self.insert_data(row, [0. for name in self.header])
53
+ self.insert_data(row, ['0.' for name in self.header])
53
54
 
54
55
  def remove_data(self, row):
55
56
  self.remove_row(row)
@@ -106,10 +107,14 @@ class TabularScanner(ScannerBase):
106
107
  ]
107
108
  distribution = DataDistribution['spread']
108
109
 
109
- def __init__(self, actuators: List['DAQ_Move']):
110
+ def __init__(self, actuators: List['DAQ_Move'], display_units=True, **kwargs):
110
111
  self.table_model: TableModelTabular = None
111
112
  self.table_view: TableViewCustom = None
112
- super().__init__(actuators=actuators)
113
+ super().__init__(actuators=actuators, display_units=display_units)
114
+ self.delegates: Iterable[SpinBoxDelegate] = []
115
+
116
+ def set_units(self):
117
+ pass
113
118
 
114
119
  @property
115
120
  def actuators(self):
@@ -124,7 +129,10 @@ class TabularScanner(ScannerBase):
124
129
 
125
130
  def update_model(self, init_data=None):
126
131
  if init_data is None:
127
- init_data = [[0. for _ in self._actuators]]
132
+ if self.display_units:
133
+ init_data = [[f'0. {act.units}' for act in self._actuators]]
134
+ else:
135
+ init_data = [['0.' for _ in self._actuators]]
128
136
 
129
137
  self.table_model = TableModelTabular(init_data, [act.title for act in self._actuators])
130
138
  self.table_view = putils.get_widget_from_tree(self.settings_tree, TableViewCustom)[0]
@@ -133,13 +141,17 @@ class TabularScanner(ScannerBase):
133
141
  self.update_table_view()
134
142
 
135
143
  def update_table_view(self):
136
- self.table_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
137
- self.table_view.horizontalHeader().setStretchLastSection(True)
144
+ self.table_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.Stretch)
145
+ # self.table_view.horizontalHeader().setStretchLastSection(True)
138
146
  self.table_view.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
139
147
  self.table_view.setSelectionMode(QtWidgets.QTableView.SingleSelection)
140
- styledItemDelegate = QtWidgets.QStyledItemDelegate()
141
- styledItemDelegate.setItemEditorFactory(gutils.SpinBoxDelegate())
142
- self.table_view.setItemDelegate(styledItemDelegate)
148
+ self.delegates = [] # ItemDelegates should have parents and be instance attribute to work with setItemDelegateForColumn
149
+ for ind_actuator, actuator in enumerate(self.actuators):
150
+
151
+ self.delegates.append(gutils.SpinBoxDelegate(self.table_view,
152
+ units=actuator.units if self.display_units else None))
153
+ self.table_view.setItemDelegateForColumn(
154
+ ind_actuator, self.delegates[-1])
143
155
 
144
156
  self.table_view.setDragEnabled(True)
145
157
  self.table_view.setDropIndicatorShown(True)
@@ -158,7 +170,7 @@ class TabularScanner(ScannerBase):
158
170
  return len(self.table_model)
159
171
 
160
172
  def set_scan(self):
161
- positions = np.array(self.table_model.get_data_all())
173
+ positions = np.array([[Q_(elt).magnitude for elt in line] for line in self.table_model.get_data_all()])
162
174
  self.get_info_from_positions(positions)
163
175
 
164
176
  def update_tabular_positions(self, positions: np.ndarray = None):
@@ -223,12 +235,12 @@ class TabularScannerSubSegmented(TabularScanner):
223
235
  'menu': True},
224
236
  ] + TabularScanner.params
225
237
 
226
- def __init__(self, actuators: List['DAQ_Move']):
238
+ def __init__(self, actuators: List['DAQ_Move'], display_units=True):
227
239
  self.table_model: TableModelTabularReadOnly = None
228
240
  self.table_view: TableViewCustom = None
229
241
  self.table_model_points: TableModelTabular = None
230
242
  self.table_view_points: TableViewCustom = None
231
- super().__init__(actuators=actuators)
243
+ super().__init__(actuators=actuators, display_units=display_units)
232
244
 
233
245
  @property
234
246
  def actuators(self):
@@ -242,7 +254,7 @@ class TabularScannerSubSegmented(TabularScanner):
242
254
 
243
255
  def update_model(self, init_data=None):
244
256
  if init_data is None:
245
- init_data = [[0. for _ in self._actuators]]
257
+ init_data = [['0.' for _ in self._actuators]]
246
258
 
247
259
  self.table_model = TableModelTabularReadOnly(init_data, [act.title for act in self._actuators])
248
260
  self.table_view = putils.get_widget_from_tree(self.settings_tree, TableViewCustom)[1]
@@ -252,7 +264,7 @@ class TabularScannerSubSegmented(TabularScanner):
252
264
 
253
265
  def update_model_points(self, init_data=None):
254
266
  if init_data is None:
255
- init_data = [[0. for _ in self._actuators]]
267
+ init_data = [['0.' for _ in self._actuators]]
256
268
 
257
269
  self.table_model_points = TableModelTabular(init_data, [act.title for act in self._actuators])
258
270
  self.table_view_points = putils.get_widget_from_tree(self.settings_tree, TableViewCustom)[0]
@@ -260,20 +272,26 @@ class TabularScannerSubSegmented(TabularScanner):
260
272
  self.update_table_view_points()
261
273
 
262
274
  def update_table_view(self):
263
- self.table_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
264
- self.table_view.horizontalHeader().setStretchLastSection(True)
275
+ self.table_view.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.Stretch)
265
276
  self.table_view.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
266
277
  self.table_view.setSelectionMode(QtWidgets.QTableView.SingleSelection)
267
- # self.table_view.setEnabled(False)
278
+ self.delegates = []
279
+ for ind_actuator, actuator in enumerate(self.actuators):
280
+ self.delegates.append(gutils.SpinBoxDelegate(self.table_view,
281
+ units=actuator.units if self.display_units else None))
282
+ self.table_view.setItemDelegateForColumn(
283
+ ind_actuator, self.delegates[-1])
268
284
 
269
285
  def update_table_view_points(self):
270
- self.table_view_points.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
271
- self.table_view_points.horizontalHeader().setStretchLastSection(True)
286
+ self.table_view_points.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.Stretch)
272
287
  self.table_view_points.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
273
288
  self.table_view_points.setSelectionMode(QtWidgets.QTableView.SingleSelection)
274
- styledItemDelegate = QtWidgets.QStyledItemDelegate()
275
- styledItemDelegate.setItemEditorFactory(gutils.SpinBoxDelegate())
276
- self.table_view.setItemDelegate(styledItemDelegate)
289
+ self.delegates_points = []
290
+ for ind_actuator, actuator in enumerate(self.actuators):
291
+ self.delegates_points.append(gutils.SpinBoxDelegate(self.table_view,
292
+ units=actuator.units if self.display_units else None))
293
+ self.table_view.setItemDelegateForColumn(
294
+ ind_actuator, self.delegates_points[-1])
277
295
 
278
296
  self.table_view_points.setDragEnabled(True)
279
297
  self.table_view_points.setDropIndicatorShown(True)
@@ -291,9 +309,8 @@ class TabularScannerSubSegmented(TabularScanner):
291
309
  def set_scan(self):
292
310
  points = [Point(coordinates) for coordinates in self.table_model_points.get_data_all()]
293
311
  positions = get_sub_segmented_positions(self.settings['tabular_step'], points)
294
-
295
312
  self.table_model.set_data_all(positions)
296
- positions = np.array(self.table_model.get_data_all())
313
+ positions = np.array([[Q_(elt).magnitude for elt in line] for line in self.table_model.get_data_all()])
297
314
  self.get_info_from_positions(positions)
298
315
 
299
316
  def update_from_scan_selector(self, scan_selector: Selector):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymodaq
3
- Version: 5.0.18
3
+ Version: 5.1.0
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
@@ -43,18 +43,19 @@ Classifier: Topic :: Scientific/Engineering :: Visualization
43
43
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
44
44
  Classifier: Topic :: Software Development :: User Interfaces
45
45
  Requires-Python: >=3.8
46
- Requires-Dist: bayesian-optimization<2.0.0
46
+ Requires-Dist: adaptive
47
+ Requires-Dist: bayesian-optimization>=2.0
47
48
  Requires-Dist: easydict
48
49
  Requires-Dist: multipledispatch
49
50
  Requires-Dist: numpy<2.0.0
50
51
  Requires-Dist: packaging
51
52
  Requires-Dist: pint
52
- Requires-Dist: pyleco<=0.4.2,>0.3; python_version >= '3.8'
53
- Requires-Dist: pymodaq-data>=5.0.18
54
- Requires-Dist: pymodaq-gui<5.0.23,>=5.0.17
53
+ Requires-Dist: pyleco>0.3; python_version >= '3.8'
54
+ Requires-Dist: pymodaq-data>=5.0.21
55
+ Requires-Dist: pymodaq-gui>=5.0.26
55
56
  Requires-Dist: pymodaq-plugin-manager>=0.0.17
56
57
  Requires-Dist: pymodaq-plugins-mock>=5.0.5
57
- Requires-Dist: pymodaq-utils<1.0.0,>=0.0.14
58
+ Requires-Dist: pymodaq-utils>=1.0.10
58
59
  Requires-Dist: pyqtgraph>=0.12
59
60
  Requires-Dist: python-dateutil
60
61
  Requires-Dist: qtconsole