pymodaq 4.1.5__py3-none-any.whl → 4.2.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.
- pymodaq/__init__.py +23 -4
- pymodaq/control_modules/daq_move.py +32 -73
- pymodaq/control_modules/daq_viewer.py +73 -98
- pymodaq/control_modules/daq_viewer_ui.py +2 -1
- pymodaq/control_modules/move_utility_classes.py +17 -7
- pymodaq/control_modules/utils.py +153 -5
- pymodaq/control_modules/viewer_utility_classes.py +31 -20
- pymodaq/dashboard.py +23 -5
- pymodaq/examples/tcp_client.py +97 -0
- pymodaq/extensions/__init__.py +4 -0
- pymodaq/extensions/bayesian/__init__.py +2 -0
- pymodaq/extensions/bayesian/bayesian_optimisation.py +673 -0
- pymodaq/extensions/bayesian/utils.py +403 -0
- pymodaq/extensions/daq_scan.py +4 -4
- pymodaq/extensions/daq_scan_ui.py +2 -1
- pymodaq/extensions/pid/pid_controller.py +12 -7
- pymodaq/extensions/pid/utils.py +9 -26
- pymodaq/extensions/utils.py +3 -0
- pymodaq/post_treatment/load_and_plot.py +42 -19
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/config_template.toml +9 -24
- pymodaq/resources/setup_plugin.py +1 -1
- pymodaq/utils/config.py +103 -5
- pymodaq/utils/daq_utils.py +35 -134
- pymodaq/utils/data.py +614 -95
- pymodaq/utils/enums.py +17 -1
- pymodaq/utils/factory.py +2 -2
- pymodaq/utils/gui_utils/custom_app.py +5 -2
- pymodaq/utils/gui_utils/dock.py +33 -4
- pymodaq/utils/gui_utils/utils.py +14 -1
- pymodaq/utils/h5modules/backends.py +9 -1
- pymodaq/utils/h5modules/data_saving.py +254 -57
- pymodaq/utils/h5modules/saving.py +1 -0
- pymodaq/utils/leco/__init__.py +25 -0
- pymodaq/utils/leco/daq_move_LECODirector.py +172 -0
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +170 -0
- pymodaq/utils/leco/desktop.ini +2 -0
- pymodaq/utils/leco/director_utils.py +58 -0
- pymodaq/utils/leco/leco_director.py +88 -0
- pymodaq/utils/leco/pymodaq_listener.py +279 -0
- pymodaq/utils/leco/utils.py +41 -0
- pymodaq/utils/managers/action_manager.py +20 -6
- pymodaq/utils/managers/parameter_manager.py +6 -4
- pymodaq/utils/managers/roi_manager.py +63 -54
- pymodaq/utils/math_utils.py +1 -1
- pymodaq/utils/plotting/data_viewers/__init__.py +3 -1
- pymodaq/utils/plotting/data_viewers/base.py +286 -0
- pymodaq/utils/plotting/data_viewers/viewer.py +29 -202
- pymodaq/utils/plotting/data_viewers/viewer0D.py +94 -47
- pymodaq/utils/plotting/data_viewers/viewer1D.py +341 -174
- pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +1 -1
- pymodaq/utils/plotting/data_viewers/viewer2D.py +271 -181
- pymodaq/utils/plotting/data_viewers/viewerND.py +26 -22
- pymodaq/utils/plotting/items/crosshair.py +3 -3
- pymodaq/utils/plotting/items/image.py +2 -1
- pymodaq/utils/plotting/plotter/plotter.py +94 -0
- pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
- pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +134 -0
- pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +78 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +1 -1
- pymodaq/utils/plotting/utils/filter.py +194 -147
- pymodaq/utils/plotting/utils/lineout.py +13 -11
- pymodaq/utils/plotting/utils/plot_utils.py +89 -12
- pymodaq/utils/scanner/__init__.py +0 -3
- pymodaq/utils/scanner/scan_config.py +1 -9
- pymodaq/utils/scanner/scan_factory.py +10 -36
- pymodaq/utils/scanner/scanner.py +3 -2
- pymodaq/utils/scanner/scanners/_1d_scanners.py +7 -5
- pymodaq/utils/scanner/scanners/_2d_scanners.py +36 -49
- pymodaq/utils/scanner/scanners/sequential.py +10 -4
- pymodaq/utils/scanner/scanners/tabular.py +10 -5
- pymodaq/utils/slicing.py +1 -1
- pymodaq/utils/tcp_ip/serializer.py +38 -5
- pymodaq/utils/tcp_ip/tcp_server_client.py +25 -17
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/METADATA +4 -2
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/RECORD +79 -63
- pymodaq/resources/config_scan_template.toml +0 -42
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/WHEEL +0 -0
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/entry_points.txt +0 -0
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -11,14 +11,6 @@ from pymodaq.utils.config import BaseConfig, getitem_recursive
|
|
|
11
11
|
|
|
12
12
|
class ScanConfig(BaseConfig):
|
|
13
13
|
"""Main class to deal with configuration values for this plugin"""
|
|
14
|
-
config_template_path =
|
|
14
|
+
config_template_path = None
|
|
15
15
|
config_name = f"scanner_settings"
|
|
16
16
|
|
|
17
|
-
def __setitem__(self, key, value):
|
|
18
|
-
if isinstance(key, tuple):
|
|
19
|
-
dic = getitem_recursive(self._config, *key, ndepth=1, create_if_missing=True)
|
|
20
|
-
if value is None: # means the setting is a group
|
|
21
|
-
value = {}
|
|
22
|
-
dic[key[-1]] = value
|
|
23
|
-
else:
|
|
24
|
-
self._config[key] = value
|
|
@@ -81,11 +81,14 @@ class ScannerBase(ScanParameterManager, metaclass=ABCMeta):
|
|
|
81
81
|
super().__init__()
|
|
82
82
|
self.positions: np.ndarray = None
|
|
83
83
|
self.n_steps = 1
|
|
84
|
-
self.
|
|
84
|
+
self.config = ScanConfig()
|
|
85
|
+
base_path = [act.title for act in actuators] + [self.scan_type, self.scan_subtype]
|
|
85
86
|
|
|
86
|
-
self.
|
|
87
|
+
self.config_saver_loader = configmod.ConfigSaverLoader(self.settings,
|
|
88
|
+
self.config,
|
|
89
|
+
base_path)
|
|
87
90
|
|
|
88
|
-
self.
|
|
91
|
+
self.actuators: List[DAQ_Move] = actuators
|
|
89
92
|
|
|
90
93
|
self.set_settings_titles()
|
|
91
94
|
self.set_settings_values()
|
|
@@ -93,32 +96,12 @@ class ScannerBase(ScanParameterManager, metaclass=ABCMeta):
|
|
|
93
96
|
if self.check_steps():
|
|
94
97
|
self.set_scan()
|
|
95
98
|
|
|
96
|
-
|
|
97
99
|
def set_settings_titles(self):
|
|
98
100
|
"""Update the settings accordingly with the selected actuators"""
|
|
99
101
|
...
|
|
100
102
|
|
|
101
103
|
def set_settings_values(self, param: Parameter = None):
|
|
102
|
-
|
|
103
|
-
param = self.settings
|
|
104
|
-
for child in param.children():
|
|
105
|
-
if len(child.children()) == 0: #means it is not a group parameter
|
|
106
|
-
path = self.actuators_name
|
|
107
|
-
path_scan = [self.scan_type, self.scan_subtype]
|
|
108
|
-
path_param = get_param_path(child)[1:]
|
|
109
|
-
path.extend(path_scan)
|
|
110
|
-
path.extend(path_param)
|
|
111
|
-
try:
|
|
112
|
-
child.setValue(self.config(*path)) # first try to load the config including the actuators name
|
|
113
|
-
except configmod.ConfigError as e:
|
|
114
|
-
try:
|
|
115
|
-
path = path_scan
|
|
116
|
-
path.extend(path_param)
|
|
117
|
-
child.setValue(self.config(*path)) # then without the actuators name
|
|
118
|
-
except Exception as e:
|
|
119
|
-
pass
|
|
120
|
-
else:
|
|
121
|
-
self.set_settings_values(child)
|
|
104
|
+
self.config_saver_loader.load_config(param)
|
|
122
105
|
|
|
123
106
|
@property
|
|
124
107
|
def actuators(self) -> List[DAQ_Move]:
|
|
@@ -127,6 +110,8 @@ class ScannerBase(ScanParameterManager, metaclass=ABCMeta):
|
|
|
127
110
|
@actuators.setter
|
|
128
111
|
def actuators(self, actuators: List[DAQ_Move]):
|
|
129
112
|
self._actuators = actuators
|
|
113
|
+
base_path = self.actuators_name + [self.scan_type, self.scan_subtype]
|
|
114
|
+
self.config_saver_loader.base_path = base_path
|
|
130
115
|
|
|
131
116
|
@property
|
|
132
117
|
def actuators_name(self) -> List[str]:
|
|
@@ -198,18 +183,7 @@ class ScannerBase(ScanParameterManager, metaclass=ABCMeta):
|
|
|
198
183
|
|
|
199
184
|
def save_scan_parameters(self):
|
|
200
185
|
if self.save_settings:
|
|
201
|
-
|
|
202
|
-
path_scan = [self.scan_type, self.scan_subtype]
|
|
203
|
-
path_actuators.extend(path_scan)
|
|
204
|
-
for param in iter_children_params(self.settings, []):
|
|
205
|
-
path = path_actuators[:]
|
|
206
|
-
path_param = get_param_path(param)[1:]
|
|
207
|
-
path.extend(path_param)
|
|
208
|
-
try:
|
|
209
|
-
self.config[tuple(path)] = param.value()
|
|
210
|
-
except Exception as e:
|
|
211
|
-
pass
|
|
212
|
-
self.config.save()
|
|
186
|
+
self.config_saver_loader.save_config()
|
|
213
187
|
|
|
214
188
|
@abstractmethod
|
|
215
189
|
def update_from_scan_selector(self, scan_selector: Selector):
|
pymodaq/utils/scanner/scanner.py
CHANGED
|
@@ -81,7 +81,8 @@ class Scanner(QObject, ParameterManager):
|
|
|
81
81
|
def set_scanner(self):
|
|
82
82
|
try:
|
|
83
83
|
self._scanner: ScannerBase = scanner_factory.get(self.settings['scan_type'],
|
|
84
|
-
self.settings['scan_sub_type'],
|
|
84
|
+
self.settings['scan_sub_type'],
|
|
85
|
+
actuators=self.actuators)
|
|
85
86
|
|
|
86
87
|
while True:
|
|
87
88
|
child = self._scanner_settings_widget.layout().takeAt(0)
|
|
@@ -93,7 +94,7 @@ class Scanner(QObject, ParameterManager):
|
|
|
93
94
|
self._scanner_settings_widget.layout().addWidget(self._scanner.settings_tree)
|
|
94
95
|
self._scanner.settings.sigTreeStateChanged.connect(self._update_steps)
|
|
95
96
|
|
|
96
|
-
except ValueError:
|
|
97
|
+
except ValueError as e:
|
|
97
98
|
pass
|
|
98
99
|
|
|
99
100
|
@property
|
|
@@ -4,7 +4,7 @@ Created the 05/12/2022
|
|
|
4
4
|
|
|
5
5
|
@author: Sebastien Weber
|
|
6
6
|
"""
|
|
7
|
-
from typing import List, Tuple, Any
|
|
7
|
+
from typing import List, Tuple, Any, TYPE_CHECKING
|
|
8
8
|
import re
|
|
9
9
|
import numpy as np
|
|
10
10
|
from pymodaq.utils.data import Axis, DataDistribution
|
|
@@ -15,6 +15,8 @@ from pymodaq.utils.plotting.scan_selector import Selector
|
|
|
15
15
|
|
|
16
16
|
from ..scan_factory import ScannerFactory, ScannerBase, ScanParameterManager
|
|
17
17
|
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from pymodaq.control_modules.daq_move import DAQ_Move
|
|
18
20
|
|
|
19
21
|
logger = set_logger(get_module_name(__file__))
|
|
20
22
|
config = configmod.Config()
|
|
@@ -59,8 +61,8 @@ class Scan1DLinear(Scan1DBase):
|
|
|
59
61
|
n_axes = 1
|
|
60
62
|
distribution = DataDistribution['uniform']
|
|
61
63
|
|
|
62
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
63
|
-
|
|
64
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
65
|
+
super().__init__(actuators=actuators)
|
|
64
66
|
|
|
65
67
|
def set_scan(self):
|
|
66
68
|
self.positions = mutils.linspace_step(self.settings['start'], self.settings['stop'],
|
|
@@ -123,7 +125,7 @@ class Scan1DSparse(Scan1DBase):
|
|
|
123
125
|
distribution = DataDistribution['uniform'] # because in 1D it doesn't matter is spread or
|
|
124
126
|
# uniform, one can easily plot both types on a regulat 1D plot
|
|
125
127
|
|
|
126
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
128
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
127
129
|
super().__init__(actuators=actuators)
|
|
128
130
|
self.settings.child('parsed_string').setOpts(tip=self.__doc__)
|
|
129
131
|
|
|
@@ -176,7 +178,7 @@ try:
|
|
|
176
178
|
]
|
|
177
179
|
distribution = DataDistribution['spread']
|
|
178
180
|
|
|
179
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
181
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
180
182
|
super().__init__(actuators=actuators)
|
|
181
183
|
|
|
182
184
|
def set_scan(self):
|
|
@@ -4,7 +4,7 @@ Created the 05/12/2022
|
|
|
4
4
|
|
|
5
5
|
@author: Sebastien Weber
|
|
6
6
|
"""
|
|
7
|
-
from typing import List, Tuple
|
|
7
|
+
from typing import List, Tuple, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
from pymodaq.utils.data import Axis, DataDistribution
|
|
@@ -18,6 +18,9 @@ from ..scan_factory import ScannerFactory, ScannerBase, ScanParameterManager
|
|
|
18
18
|
logger = set_logger(get_module_name(__file__))
|
|
19
19
|
config = configmod.Config()
|
|
20
20
|
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from pymodaq.control_modules.daq_move import DAQ_Move
|
|
23
|
+
|
|
21
24
|
|
|
22
25
|
class Scan2DBase(ScannerBase):
|
|
23
26
|
params = [{'title': 'Ax1:', 'name': 'axis1', 'type': 'group',
|
|
@@ -29,7 +32,7 @@ class Scan2DBase(ScannerBase):
|
|
|
29
32
|
]
|
|
30
33
|
axes = ('axis1','axis2')
|
|
31
34
|
n_axes = 2
|
|
32
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
35
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
33
36
|
super().__init__(actuators=actuators)
|
|
34
37
|
self.axes_unique = []
|
|
35
38
|
|
|
@@ -40,20 +43,20 @@ class Scan2DLinear(Scan2DBase):
|
|
|
40
43
|
params = [{'title': 'Ax1:', 'name': 'axis1', 'type': 'group',
|
|
41
44
|
'children':[
|
|
42
45
|
{'title': 'Start Ax1:', 'name': 'start_axis1', 'type': 'float',
|
|
43
|
-
'value':
|
|
46
|
+
'value': 0.},
|
|
44
47
|
{'title': 'Stop Ax1:', 'name': 'stop_axis1', 'type': 'float',
|
|
45
|
-
'value':
|
|
48
|
+
'value': 1.},
|
|
46
49
|
{'title': 'Step Ax1:', 'name': 'step_axis1', 'type': 'float',
|
|
47
|
-
'value':
|
|
50
|
+
'value': 0.1},
|
|
48
51
|
]},
|
|
49
52
|
{'title': 'Ax2:', 'name': 'axis2', 'type': 'group',
|
|
50
53
|
'children':[
|
|
51
54
|
{'title': 'Start Ax2:', 'name': 'start_axis2', 'type': 'float',
|
|
52
|
-
'value':
|
|
55
|
+
'value': 0.},
|
|
53
56
|
{'title': 'Stop Ax2:', 'name': 'stop_axis2', 'type': 'float',
|
|
54
|
-
'value':
|
|
57
|
+
'value': 1.},
|
|
55
58
|
{'title': 'Step Ax2:', 'name': 'step_axis2', 'type': 'float',
|
|
56
|
-
'value':
|
|
59
|
+
'value': 0.1},
|
|
57
60
|
]},
|
|
58
61
|
]
|
|
59
62
|
n_axes = 2
|
|
@@ -61,13 +64,13 @@ class Scan2DLinear(Scan2DBase):
|
|
|
61
64
|
scan_type = 'Scan2D'
|
|
62
65
|
scan_subtype = 'Linear'
|
|
63
66
|
|
|
64
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
67
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
65
68
|
super().__init__(actuators=actuators)
|
|
66
69
|
|
|
67
70
|
def get_pos(self):
|
|
68
|
-
starts = np.array([self.settings[ax,f'start_{ax}'] for ax in self.axes])
|
|
69
|
-
stops = np.array([self.settings[ax,f'stop_{ax}'] for ax in self.axes])
|
|
70
|
-
steps = np.array([self.settings[ax,f'step_{ax}'] for ax in self.axes])
|
|
71
|
+
starts = np.array([self.settings[ax, f'start_{ax}'] for ax in self.axes])
|
|
72
|
+
stops = np.array([self.settings[ax, f'stop_{ax}'] for ax in self.axes])
|
|
73
|
+
steps = np.array([self.settings[ax, f'step_{ax}'] for ax in self.axes])
|
|
71
74
|
return starts, stops, steps
|
|
72
75
|
|
|
73
76
|
def evaluate_steps(self) -> int:
|
|
@@ -101,10 +104,9 @@ class Scan2DLinear(Scan2DBase):
|
|
|
101
104
|
for i,ax in enumerate(self.axes):
|
|
102
105
|
title = self.actuators[i].title
|
|
103
106
|
self.settings.child(ax).setOpts(title=title)
|
|
104
|
-
self.settings.child(ax,f'start_{ax}').setOpts(title=f'{title} start:')
|
|
105
|
-
self.settings.child(ax,f'stop_{ax}').setOpts(title=f'{title} stop:')
|
|
106
|
-
self.settings.child(ax,f'step_{ax}').setOpts(title=f'{title} step:')
|
|
107
|
-
|
|
107
|
+
self.settings.child(ax, f'start_{ax}').setOpts(title=f'{title} start:')
|
|
108
|
+
self.settings.child(ax, f'stop_{ax}').setOpts(title=f'{title} stop:')
|
|
109
|
+
self.settings.child(ax, f'step_{ax}').setOpts(title=f'{title} step:')
|
|
108
110
|
|
|
109
111
|
def get_nav_axes(self) -> List[Axis]:
|
|
110
112
|
return [Axis(label=f'{act.title}',
|
|
@@ -127,12 +129,11 @@ class Scan2DLinear(Scan2DBase):
|
|
|
127
129
|
self.settings.child(ax,f'stop_{ax}').setValue(coordinates[1, i])
|
|
128
130
|
|
|
129
131
|
|
|
130
|
-
|
|
131
132
|
@ScannerFactory.register()
|
|
132
133
|
class Scan2DLinearBF(Scan2DLinear):
|
|
133
134
|
scan_subtype = 'LinearBackForce'
|
|
134
135
|
|
|
135
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
136
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
136
137
|
super().__init__(actuators=actuators)
|
|
137
138
|
|
|
138
139
|
def set_scan(self):
|
|
@@ -162,7 +163,7 @@ class Scan2DLinearBF(Scan2DLinear):
|
|
|
162
163
|
class Scan2DRandom(Scan2DLinear):
|
|
163
164
|
scan_subtype = 'Random'
|
|
164
165
|
|
|
165
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
166
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
166
167
|
super().__init__(actuators=actuators)
|
|
167
168
|
|
|
168
169
|
def set_scan(self):
|
|
@@ -175,28 +176,28 @@ class Scan2DRandom(Scan2DLinear):
|
|
|
175
176
|
class Scan2DSpiral(Scan2DLinear):
|
|
176
177
|
scan_subtype = 'Spiral'
|
|
177
178
|
params = [{'title': 'Npts/axis', 'name': 'npts_by_axis', 'type': 'int', 'min': 1,
|
|
178
|
-
'value':
|
|
179
|
+
'value': 10},
|
|
179
180
|
{'title': 'Ax1:', 'name': 'axis1', 'type': 'group',
|
|
180
181
|
'children': [
|
|
181
182
|
{'title': 'Center Ax1:', 'name': 'center_axis1', 'type': 'float',
|
|
182
|
-
'value':
|
|
183
|
+
'value': 0.},
|
|
183
184
|
{'title': 'Rmax Ax1:', 'name': 'rmax_axis1', 'type': 'float',
|
|
184
|
-
'value':
|
|
185
|
+
'value': 5.},
|
|
185
186
|
{'title': 'Step Ax1:', 'name': 'step_axis1', 'type': 'float',
|
|
186
187
|
'value': 0., 'readonly': True},
|
|
187
188
|
]},
|
|
188
189
|
{'title': 'Ax2:', 'name': 'axis2', 'type': 'group',
|
|
189
190
|
'children': [
|
|
190
191
|
{'title': 'Center Ax2:', 'name': 'center_axis2', 'type': 'float',
|
|
191
|
-
'value':
|
|
192
|
+
'value': 0.},
|
|
192
193
|
{'title': 'Rmax Ax2:', 'name': 'rmax_axis2', 'type': 'float',
|
|
193
|
-
'value':
|
|
194
|
+
'value': 5.},
|
|
194
195
|
{'title': 'Step Ax2:', 'name': 'step_axis2', 'type': 'float',
|
|
195
196
|
'value': 0., 'readonly': True},
|
|
196
197
|
]},
|
|
197
198
|
]
|
|
198
199
|
|
|
199
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
200
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
200
201
|
super().__init__(actuators=actuators)
|
|
201
202
|
|
|
202
203
|
def set_settings_titles(self):
|
|
@@ -204,17 +205,9 @@ class Scan2DSpiral(Scan2DLinear):
|
|
|
204
205
|
for i,ax in enumerate(self.axes):
|
|
205
206
|
title = self.actuators[i].title
|
|
206
207
|
self.settings.child(ax).setOpts(title=title)
|
|
207
|
-
self.settings.child(ax,f'center_{ax}').setOpts(title=f'{title} center:')
|
|
208
|
-
self.settings.child(ax,f'rmax_{ax}').setOpts(title=f'{title} rmax:')
|
|
209
|
-
self.settings.child(ax,f'step_{ax}').setOpts(title=f'{title} step:')
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
# self.settings.child('center_axis1').setOpts(title=f'Center {self.actuators[0].title}:')
|
|
213
|
-
# self.settings.child('rmax_axis1').setOpts(title=f'Rmax {self.actuators[0].title}:')
|
|
214
|
-
# self.settings.child('step_axis1').setOpts(title=f'Step {self.actuators[0].title}:')
|
|
215
|
-
# self.settings.child('center_axis2').setOpts(title=f'Center {self.actuators[1].title}:')
|
|
216
|
-
# self.settings.child('rmax_axis2').setOpts(title=f'Rmax {self.actuators[1].title}:')
|
|
217
|
-
# self.settings.child('step_axis2').setOpts(title=f'Step {self.actuators[1].title}:')
|
|
208
|
+
self.settings.child(ax, f'center_{ax}').setOpts(title=f'{title} center:')
|
|
209
|
+
self.settings.child(ax, f'rmax_{ax}').setOpts(title=f'{title} rmax:')
|
|
210
|
+
self.settings.child(ax, f'step_{ax}').setOpts(title=f'{title} step:')
|
|
218
211
|
|
|
219
212
|
def value_changed(self, param):
|
|
220
213
|
starts, rmaxs, rsteps = self.get_pos()
|
|
@@ -234,10 +227,8 @@ class Scan2DSpiral(Scan2DLinear):
|
|
|
234
227
|
r_steps: np.ndarray
|
|
235
228
|
steps size in both directions
|
|
236
229
|
"""
|
|
237
|
-
centers = np.array([self.settings[ax,f'center_{ax}'] for ax in self.axes])
|
|
238
|
-
rmaxs = np.array([self.settings[ax,f'rmax_{ax}'] for ax in self.axes])
|
|
239
|
-
# centers = np.array([self.settings['center_axis1'], self.settings['center_axis2']])
|
|
240
|
-
# rmaxs = np.array([self.settings['rmax_axis1'], self.settings['rmax_axis2']])
|
|
230
|
+
centers = np.array([self.settings[ax, f'center_{ax}'] for ax in self.axes])
|
|
231
|
+
rmaxs = np.array([self.settings[ax, f'rmax_{ax}'] for ax in self.axes])
|
|
241
232
|
r_steps = 2 * rmaxs / self.settings['npts_by_axis']
|
|
242
233
|
return centers, rmaxs, r_steps
|
|
243
234
|
|
|
@@ -290,14 +281,10 @@ class Scan2DSpiral(Scan2DLinear):
|
|
|
290
281
|
coordinates = scan_selector.get_coordinates()
|
|
291
282
|
if coordinates.shape == (2, 2):
|
|
292
283
|
for i,ax in enumerate(self.axes):
|
|
293
|
-
self.settings.child(ax,f'center_{ax}').setValue(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
# self.settings.child('center_axis1').setValue((coordinates[0, 0] + coordinates[1, 0]) / 2)
|
|
298
|
-
# self.settings.child('center_axis2').setValue((coordinates[0, 1] + coordinates[1, 1]) / 2)
|
|
299
|
-
# self.settings.child('rmax_axis1').setValue(abs(coordinates[1, 0] - coordinates[0, 0]) / 2)
|
|
300
|
-
# self.settings.child('rmax_axis2').setValue(abs(coordinates[1, 1] - coordinates[0, 1]) / 2)
|
|
284
|
+
self.settings.child(ax, f'center_{ax}').setValue(
|
|
285
|
+
(coordinates[0, i] + coordinates[1, i]) / 2)
|
|
286
|
+
self.settings.child(ax, f'rmax_{ax}').setValue(
|
|
287
|
+
(coordinates[0, i] - coordinates[1, i]) / 2)
|
|
301
288
|
|
|
302
289
|
|
|
303
290
|
try:
|
|
@@ -333,7 +320,7 @@ try:
|
|
|
333
320
|
]
|
|
334
321
|
distribution = DataDistribution['spread']
|
|
335
322
|
|
|
336
|
-
def __init__(self, actuators: List = None, **_ignored):
|
|
323
|
+
def __init__(self, actuators: List['DAQ_Move'] = None, **_ignored):
|
|
337
324
|
super().__init__(actuators=actuators)
|
|
338
325
|
|
|
339
326
|
def set_scan(self):
|
|
@@ -4,7 +4,7 @@ Created the 05/12/2022
|
|
|
4
4
|
|
|
5
5
|
@author: Sebastien Weber
|
|
6
6
|
"""
|
|
7
|
-
from typing import List, Tuple
|
|
7
|
+
from typing import List, Tuple, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
|
|
@@ -23,6 +23,10 @@ logger = set_logger(get_module_name(__file__))
|
|
|
23
23
|
config = configmod.Config()
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from pymodaq.control_modules.daq_move import DAQ_Move
|
|
28
|
+
|
|
29
|
+
|
|
26
30
|
class TableModelSequential(gutils.TableModel):
|
|
27
31
|
"""Table Model for the Model/View Qt framework dedicated to the Sequential scan mode"""
|
|
28
32
|
def __init__(self, data, **kwargs):
|
|
@@ -84,7 +88,7 @@ class SequentialScanner(ScannerBase):
|
|
|
84
88
|
distribution = DataDistribution['uniform']
|
|
85
89
|
n_axes = 1
|
|
86
90
|
|
|
87
|
-
def __init__(self, actuators: List[
|
|
91
|
+
def __init__(self, actuators: List['DAQ_Move']):
|
|
88
92
|
|
|
89
93
|
self.table_model: TableModelSequential = None
|
|
90
94
|
self.table_view: TableViewCustom = None
|
|
@@ -96,8 +100,10 @@ class SequentialScanner(ScannerBase):
|
|
|
96
100
|
return self._actuators
|
|
97
101
|
|
|
98
102
|
@actuators.setter
|
|
99
|
-
def actuators(self,
|
|
100
|
-
self._actuators =
|
|
103
|
+
def actuators(self, actuators):
|
|
104
|
+
self._actuators = actuators
|
|
105
|
+
base_path = self.actuators_name + [self.scan_type, self.scan_subtype]
|
|
106
|
+
self.config_saver_loader.base_path = base_path
|
|
101
107
|
self.update_model()
|
|
102
108
|
|
|
103
109
|
def update_model(self, init_data=None):
|
|
@@ -4,7 +4,7 @@ Created the 05/12/2022
|
|
|
4
4
|
|
|
5
5
|
@author: Sebastien Weber
|
|
6
6
|
"""
|
|
7
|
-
from typing import List, Tuple
|
|
7
|
+
from typing import List, Tuple, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
|
|
@@ -20,6 +20,9 @@ from pymodaq.utils.parameter.pymodaq_ptypes import TableViewCustom
|
|
|
20
20
|
from pymodaq.utils.plotting.scan_selector import Selector
|
|
21
21
|
from pymodaq.utils.plotting.utils.plot_utils import Point, get_sub_segmented_positions
|
|
22
22
|
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from pymodaq.control_modules.daq_move import DAQ_Move
|
|
25
|
+
|
|
23
26
|
|
|
24
27
|
logger = set_logger(get_module_name(__file__))
|
|
25
28
|
config = configmod.Config()
|
|
@@ -103,7 +106,7 @@ class TabularScanner(ScannerBase):
|
|
|
103
106
|
]
|
|
104
107
|
distribution = DataDistribution['spread']
|
|
105
108
|
|
|
106
|
-
def __init__(self, actuators: List[
|
|
109
|
+
def __init__(self, actuators: List['DAQ_Move']):
|
|
107
110
|
self.table_model: TableModelTabular = None
|
|
108
111
|
self.table_view: TableViewCustom = None
|
|
109
112
|
super().__init__(actuators=actuators)
|
|
@@ -113,8 +116,10 @@ class TabularScanner(ScannerBase):
|
|
|
113
116
|
return self._actuators
|
|
114
117
|
|
|
115
118
|
@actuators.setter
|
|
116
|
-
def actuators(self,
|
|
117
|
-
self._actuators =
|
|
119
|
+
def actuators(self, actuators):
|
|
120
|
+
self._actuators = actuators
|
|
121
|
+
base_path = self.actuators_name + [self.scan_type, self.scan_subtype]
|
|
122
|
+
self.config_saver_loader.base_path = base_path
|
|
118
123
|
self.update_model()
|
|
119
124
|
|
|
120
125
|
def update_model(self, init_data=None):
|
|
@@ -218,7 +223,7 @@ class TabularScannerSubSegmented(TabularScanner):
|
|
|
218
223
|
'menu': True},
|
|
219
224
|
] + TabularScanner.params
|
|
220
225
|
|
|
221
|
-
def __init__(self, actuators: List[
|
|
226
|
+
def __init__(self, actuators: List['DAQ_Move']):
|
|
222
227
|
self.table_model: TableModelTabularReadOnly = None
|
|
223
228
|
self.table_view: TableViewCustom = None
|
|
224
229
|
self.table_model_points: TableModelTabular = None
|
pymodaq/utils/slicing.py
CHANGED
|
@@ -4,6 +4,7 @@ Created the 20/10/2023
|
|
|
4
4
|
|
|
5
5
|
@author: Sebastien Weber
|
|
6
6
|
"""
|
|
7
|
+
from base64 import b64encode, b64decode
|
|
7
8
|
import numbers
|
|
8
9
|
from typing import Tuple, List, Union, TYPE_CHECKING, Iterable
|
|
9
10
|
|
|
@@ -16,6 +17,18 @@ if TYPE_CHECKING:
|
|
|
16
17
|
from pymodaq.utils.tcp_ip.mysocket import Socket
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
SERIALIZABLE = Union[
|
|
21
|
+
int,
|
|
22
|
+
str,
|
|
23
|
+
numbers.Number,
|
|
24
|
+
list,
|
|
25
|
+
np.ndarray,
|
|
26
|
+
Axis,
|
|
27
|
+
DataWithAxes,
|
|
28
|
+
DataToExport,
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
19
32
|
class SocketString:
|
|
20
33
|
"""Mimic the Socket object but actually using a bytes string not a socket connection
|
|
21
34
|
|
|
@@ -68,9 +81,10 @@ class SocketString:
|
|
|
68
81
|
|
|
69
82
|
|
|
70
83
|
class Serializer:
|
|
71
|
-
"""Used to Serialize to bytes python objects, numpy arrays and PyMoDAQ DataWithAxes and
|
|
84
|
+
"""Used to Serialize to bytes python objects, numpy arrays and PyMoDAQ DataWithAxes and
|
|
85
|
+
DataToExport objects"""
|
|
72
86
|
|
|
73
|
-
def __init__(self, obj:
|
|
87
|
+
def __init__(self, obj: SERIALIZABLE = None):
|
|
74
88
|
self._bytes_string = b''
|
|
75
89
|
self._obj = obj
|
|
76
90
|
|
|
@@ -107,6 +121,11 @@ class Serializer:
|
|
|
107
121
|
return self.list_serialization(self._obj)
|
|
108
122
|
elif isinstance(self._obj, bool):
|
|
109
123
|
return self.scalar_serialization(int(self._obj))
|
|
124
|
+
raise ValueError
|
|
125
|
+
|
|
126
|
+
def to_b64_string(self) -> str:
|
|
127
|
+
b = self.to_bytes()
|
|
128
|
+
return b64encode(b).decode()
|
|
110
129
|
|
|
111
130
|
@staticmethod
|
|
112
131
|
def int_to_bytes(an_integer: int) -> bytes:
|
|
@@ -123,17 +142,17 @@ class Serializer:
|
|
|
123
142
|
if not isinstance(an_integer, int):
|
|
124
143
|
raise TypeError(f'{an_integer} should be an integer, not a {type(an_integer)}')
|
|
125
144
|
elif an_integer < 0:
|
|
126
|
-
raise ValueError(
|
|
145
|
+
raise ValueError('Can only serialize unsigned integer using this method')
|
|
127
146
|
return an_integer.to_bytes(4, 'big')
|
|
128
147
|
|
|
129
148
|
@staticmethod
|
|
130
149
|
def str_to_bytes(message: str) -> bytes:
|
|
131
150
|
if not isinstance(message, str):
|
|
132
|
-
raise TypeError(
|
|
151
|
+
raise TypeError('Can only serialize str object using this method')
|
|
133
152
|
return message.encode()
|
|
134
153
|
|
|
135
154
|
@classmethod
|
|
136
|
-
def str_len_to_bytes(cls, message: str) -> (bytes, bytes):
|
|
155
|
+
def str_len_to_bytes(cls, message: Union[str, bytes]) -> (bytes, bytes):
|
|
137
156
|
""" Convert a string and its length to two bytes
|
|
138
157
|
Parameters
|
|
139
158
|
----------
|
|
@@ -391,6 +410,7 @@ class Serializer:
|
|
|
391
410
|
* serialize the origin
|
|
392
411
|
* serialize the nav_index tuple as a list of int
|
|
393
412
|
* serialize the list of axis
|
|
413
|
+
* serialize the errors attributes (None or list(np.ndarray))
|
|
394
414
|
* serialize the list of names of extra attributes
|
|
395
415
|
* serialize the extra attributes
|
|
396
416
|
"""
|
|
@@ -409,6 +429,12 @@ class Serializer:
|
|
|
409
429
|
bytes_string += self.string_serialization(dwa.origin)
|
|
410
430
|
bytes_string += self.list_serialization(list(dwa.nav_indexes))
|
|
411
431
|
bytes_string += self.list_serialization(dwa.axes)
|
|
432
|
+
if dwa.errors is None:
|
|
433
|
+
errors = [] # have to use this extra attribute as if I force dwa.errors = [], it will be
|
|
434
|
+
#internally modified as None again
|
|
435
|
+
else:
|
|
436
|
+
errors = dwa.errors
|
|
437
|
+
bytes_string += self.list_serialization(errors)
|
|
412
438
|
bytes_string += self.list_serialization(dwa.extra_attributes)
|
|
413
439
|
for attribute in dwa.extra_attributes:
|
|
414
440
|
bytes_string += self.type_and_object_serialization(getattr(dwa, attribute))
|
|
@@ -468,6 +494,10 @@ class DeSerializer:
|
|
|
468
494
|
bytes_string = SocketString(bytes_string)
|
|
469
495
|
self._bytes_string = bytes_string
|
|
470
496
|
|
|
497
|
+
@classmethod
|
|
498
|
+
def from_b64_string(cls, b64_string: Union[bytes, str]) -> "DeSerializer":
|
|
499
|
+
return cls(b64decode(b64_string))
|
|
500
|
+
|
|
471
501
|
@staticmethod
|
|
472
502
|
def bytes_to_string(message: bytes) -> str:
|
|
473
503
|
return message.decode()
|
|
@@ -670,6 +700,9 @@ class DeSerializer:
|
|
|
670
700
|
nav_indexes=tuple(self.list_deserialization()),
|
|
671
701
|
axes=self.list_deserialization(),
|
|
672
702
|
)
|
|
703
|
+
errors = self.list_deserialization()
|
|
704
|
+
if len(errors) != 0:
|
|
705
|
+
dwa.errors = errors
|
|
673
706
|
dwa.extra_attributes = self.list_deserialization()
|
|
674
707
|
for attribute in dwa.extra_attributes:
|
|
675
708
|
setattr(dwa, attribute, self.object_deserialization())
|