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.
- pymodaq/__init__.py +55 -89
- pymodaq/control_modules/daq_move.py +123 -52
- pymodaq/control_modules/daq_move_ui.py +42 -11
- pymodaq/control_modules/daq_viewer.py +30 -13
- pymodaq/control_modules/move_utility_classes.py +345 -78
- pymodaq/control_modules/utils.py +26 -9
- pymodaq/control_modules/viewer_utility_classes.py +51 -14
- pymodaq/daq_utils/daq_utils.py +6 -0
- pymodaq/dashboard.py +532 -263
- pymodaq/examples/qt_less_standalone_module.py +128 -0
- pymodaq/extensions/bayesian/bayesian_optimisation.py +30 -21
- pymodaq/extensions/bayesian/utils.py +6 -3
- pymodaq/extensions/daq_logger/__init__.py +1 -0
- pymodaq/extensions/daq_logger/daq_logger.py +4 -5
- pymodaq/extensions/daq_scan.py +1 -3
- pymodaq/extensions/daq_scan_ui.py +7 -9
- pymodaq/extensions/pid/__init__.py +0 -1
- pymodaq/extensions/pid/actuator_controller.py +13 -0
- pymodaq/extensions/pid/daq_move_PID.py +25 -46
- pymodaq/extensions/pid/pid_controller.py +48 -40
- pymodaq/extensions/pid/utils.py +3 -2
- pymodaq/extensions/utils.py +41 -7
- pymodaq/resources/setup_plugin.py +1 -0
- pymodaq/updater.py +107 -0
- pymodaq/utils/chrono_timer.py +6 -7
- pymodaq/utils/daq_utils.py +6 -3
- pymodaq/utils/data.py +11 -16
- pymodaq/utils/enums.py +6 -0
- pymodaq/utils/gui_utils/loader_utils.py +27 -2
- pymodaq/utils/gui_utils/utils.py +9 -12
- pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
- pymodaq/utils/leco/daq_move_LECODirector.py +21 -14
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +13 -8
- pymodaq/utils/leco/pymodaq_listener.py +8 -7
- pymodaq/utils/leco/utils.py +33 -7
- pymodaq/utils/managers/modules_manager.py +20 -10
- pymodaq/utils/managers/overshoot_manager.py +45 -1
- pymodaq/utils/managers/preset_manager.py +22 -46
- pymodaq/utils/managers/preset_manager_utils.py +17 -13
- pymodaq/utils/managers/remote_manager.py +1 -1
- pymodaq/utils/messenger.py +6 -0
- pymodaq/utils/parameter/__init__.py +5 -1
- pymodaq/utils/tcp_ip/mysocket.py +4 -110
- pymodaq/utils/tcp_ip/serializer.py +4 -769
- pymodaq/utils/tcp_ip/tcp_server_client.py +5 -5
- pymodaq-5.0.1.dist-info/METADATA +242 -0
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/RECORD +51 -52
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/WHEEL +1 -1
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/entry_points.txt +1 -0
- pymodaq/examples/custom_app.py +0 -255
- pymodaq/examples/custom_viewer.py +0 -112
- pymodaq/examples/parameter_ex.py +0 -158
- pymodaq/examples/preset_MockCamera.xml +0 -1
- pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py +0 -142
- pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui +0 -232
- pymodaq/post_treatment/daq_measurement/daq_measurement_main.py +0 -391
- pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -2
- pymodaq-5.0.0.dist-info/METADATA +0 -166
- /pymodaq/{post_treatment/daq_measurement → daq_utils}/__init__.py +0 -0
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -38,8 +38,6 @@ class DAQ_Move_LECODirector(LECODirector, DAQ_Move_base):
|
|
|
38
38
|
settings: Parameter
|
|
39
39
|
controller: ActuatorDirector
|
|
40
40
|
|
|
41
|
-
is_multiaxes = False
|
|
42
|
-
axes_names = []
|
|
43
41
|
params_client = [] # parameters of a client grabber
|
|
44
42
|
data_actuator_type = DataActuatorType['float'] # DataActuatorType['DataActuator']
|
|
45
43
|
|
|
@@ -47,19 +45,21 @@ class DAQ_Move_LECODirector(LECODirector, DAQ_Move_base):
|
|
|
47
45
|
'get_actuator_value', 'stop_motion', 'position_is',
|
|
48
46
|
'move_done']
|
|
49
47
|
socket_types = ["ACTUATOR"]
|
|
50
|
-
params =
|
|
51
|
-
] + comon_parameters_fun(is_multiaxes=is_multiaxes, axes_names=axes_names) + leco_parameters
|
|
48
|
+
params = comon_parameters_fun() + leco_parameters
|
|
52
49
|
|
|
53
50
|
def __init__(self, parent=None, params_state=None, **kwargs) -> None:
|
|
54
51
|
super().__init__(parent=parent,
|
|
55
52
|
params_state=params_state, **kwargs)
|
|
56
53
|
self.register_rpc_methods((
|
|
57
54
|
self.set_info,
|
|
55
|
+
))
|
|
56
|
+
for method in (
|
|
58
57
|
self.set_position,
|
|
59
58
|
self.set_move_done,
|
|
60
59
|
self.set_x_axis,
|
|
61
60
|
self.set_y_axis,
|
|
62
|
-
)
|
|
61
|
+
):
|
|
62
|
+
self.listener.register_binary_rpc_method(method, accept_binary_input=True)
|
|
63
63
|
|
|
64
64
|
# copied, I think it is good:
|
|
65
65
|
self.settings.child('bounds').hide()
|
|
@@ -143,22 +143,29 @@ class DAQ_Move_LECODirector(LECODirector, DAQ_Move_base):
|
|
|
143
143
|
self.controller.stop_motion()
|
|
144
144
|
|
|
145
145
|
# Methods accessible via remote calls
|
|
146
|
-
def _set_position_value(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
def _set_position_value(
|
|
147
|
+
self, position: Union[str, float, None], additional_payload=None
|
|
148
|
+
) -> DataActuator:
|
|
149
|
+
if position:
|
|
150
|
+
if isinstance(position, str):
|
|
151
|
+
deserializer = DeSerializer.from_b64_string(position)
|
|
152
|
+
pos = deserializer.dwa_deserialization()
|
|
153
|
+
else:
|
|
154
|
+
pos = DataActuator(data=position)
|
|
155
|
+
elif additional_payload is not None:
|
|
156
|
+
pos = DeSerializer(additional_payload[0]).dwa_deserialization()
|
|
150
157
|
else:
|
|
151
|
-
|
|
158
|
+
raise ValueError("No position given")
|
|
152
159
|
pos = self.get_position_with_scaling(pos) # type: ignore
|
|
153
160
|
self._current_value = pos
|
|
154
161
|
return pos
|
|
155
162
|
|
|
156
|
-
def set_position(self, position: Union[str, float]) -> None:
|
|
157
|
-
pos = self._set_position_value(position=position)
|
|
163
|
+
def set_position(self, position: Union[str, float, None], additional_payload=None) -> None:
|
|
164
|
+
pos = self._set_position_value(position=position, additional_payload=additional_payload)
|
|
158
165
|
self.emit_status(ThreadCommand('get_actuator_value', [pos]))
|
|
159
166
|
|
|
160
|
-
def set_move_done(self, position: Union[str, float]) -> None:
|
|
161
|
-
pos = self._set_position_value(position=position)
|
|
167
|
+
def set_move_done(self, position: Union[str, float, None], additional_payload=None) -> None:
|
|
168
|
+
pos = self._set_position_value(position=position, additional_payload=additional_payload)
|
|
162
169
|
self.emit_status(ThreadCommand('move_done', [pos]))
|
|
163
170
|
|
|
164
171
|
def set_x_axis(self, data, label: str = "", units: str = "") -> None:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
from typing import Union
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Optional, Union
|
|
3
3
|
|
|
4
4
|
from easydict import EasyDict as edict
|
|
5
5
|
|
|
@@ -29,16 +29,18 @@ class DAQ_xDViewer_LECODirector(LECODirector, DAQ_Viewer_base):
|
|
|
29
29
|
"Status", "Done", "Server Closed",
|
|
30
30
|
"Info", "Infos", "Info_xml", 'x_axis', 'y_axis']
|
|
31
31
|
socket_types = ["GRABBER"]
|
|
32
|
-
params =
|
|
33
|
-
] + comon_parameters + leco_parameters
|
|
32
|
+
params = comon_parameters + leco_parameters
|
|
34
33
|
|
|
35
34
|
def __init__(self, parent=None, params_state=None, grabber_type: str = "0D", **kwargs) -> None:
|
|
36
35
|
super().__init__(parent=parent, params_state=params_state, **kwargs)
|
|
37
36
|
self.register_rpc_methods((
|
|
38
37
|
self.set_x_axis,
|
|
39
38
|
self.set_y_axis,
|
|
40
|
-
self.set_data,
|
|
41
39
|
))
|
|
40
|
+
for method in (
|
|
41
|
+
self.set_data,
|
|
42
|
+
):
|
|
43
|
+
self.listener.register_binary_rpc_method(method, accept_binary_input=True)
|
|
42
44
|
|
|
43
45
|
self.client_type = "GRABBER"
|
|
44
46
|
self.x_axis = None
|
|
@@ -150,7 +152,8 @@ class DAQ_xDViewer_LECODirector(LECODirector, DAQ_Viewer_base):
|
|
|
150
152
|
self.y_axis = dict(data=data, label=label, units=units)
|
|
151
153
|
self.emit_y_axis()
|
|
152
154
|
|
|
153
|
-
def set_data(self, data: Union[list, str
|
|
155
|
+
def set_data(self, data: Union[list, str, None],
|
|
156
|
+
additional_payload: Optional[list[bytes]]=None) -> None:
|
|
154
157
|
"""
|
|
155
158
|
Set the grabbed data signal.
|
|
156
159
|
|
|
@@ -160,10 +163,12 @@ class DAQ_xDViewer_LECODirector(LECODirector, DAQ_Viewer_base):
|
|
|
160
163
|
"""
|
|
161
164
|
if isinstance(data, str):
|
|
162
165
|
deserializer = DeSerializer.from_b64_string(data)
|
|
163
|
-
|
|
164
|
-
|
|
166
|
+
elif additional_payload is not None:
|
|
167
|
+
deserializer = DeSerializer(additional_payload[0])
|
|
165
168
|
else:
|
|
166
169
|
raise NotImplementedError("Not implemented to set a list of values.")
|
|
170
|
+
dte = deserializer.dte_deserialization()
|
|
171
|
+
self.dte_signal.emit(dte)
|
|
167
172
|
|
|
168
173
|
|
|
169
174
|
if __name__ == '__main__':
|
|
@@ -16,8 +16,9 @@ from qtpy.QtCore import QObject, Signal # type: ignore
|
|
|
16
16
|
|
|
17
17
|
from pymodaq_utils.utils import ThreadCommand
|
|
18
18
|
from pymodaq_gui.parameter import ioxml
|
|
19
|
-
from
|
|
20
|
-
from
|
|
19
|
+
from pymodaq_data.data import DataWithAxes
|
|
20
|
+
from pymodaq_utils.serialize.serializer_legacy import SERIALIZABLE, DeSerializer
|
|
21
|
+
from pymodaq.utils.leco.utils import binary_serialization_to_kwargs
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
class LECOClientCommands(StrEnum):
|
|
@@ -220,7 +221,7 @@ class ActorListener(PymodaqListener):
|
|
|
220
221
|
self.communicator.ask_rpc(
|
|
221
222
|
receiver=self.remote_name,
|
|
222
223
|
method="set_data",
|
|
223
|
-
|
|
224
|
+
**binary_serialization_to_kwargs(value),
|
|
224
225
|
)
|
|
225
226
|
|
|
226
227
|
elif command.command == 'send_info':
|
|
@@ -236,14 +237,14 @@ class ActorListener(PymodaqListener):
|
|
|
236
237
|
value = command.attribute[0] # type: ignore
|
|
237
238
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
238
239
|
method="set_position",
|
|
239
|
-
|
|
240
|
+
**binary_serialization_to_kwargs(value, data_key="position"),
|
|
240
241
|
)
|
|
241
242
|
|
|
242
243
|
elif command.command == LECOMoveCommands.MOVE_DONE:
|
|
243
244
|
value = command.attribute[0] # type: ignore
|
|
244
245
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
245
246
|
method="set_move_done",
|
|
246
|
-
|
|
247
|
+
**binary_serialization_to_kwargs(value, data_key="position"),
|
|
247
248
|
)
|
|
248
249
|
|
|
249
250
|
elif command.command == 'x_axis':
|
|
@@ -251,7 +252,7 @@ class ActorListener(PymodaqListener):
|
|
|
251
252
|
if isinstance(value, SERIALIZABLE):
|
|
252
253
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
253
254
|
method="set_x_axis",
|
|
254
|
-
|
|
255
|
+
**binary_serialization_to_kwargs(value),
|
|
255
256
|
)
|
|
256
257
|
elif isinstance(value, dict):
|
|
257
258
|
self.communicator.ask_rpc(receiver=self.remote_name, method="set_x_axis", **value)
|
|
@@ -263,7 +264,7 @@ class ActorListener(PymodaqListener):
|
|
|
263
264
|
if isinstance(value, SERIALIZABLE):
|
|
264
265
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
265
266
|
method="set_y_axis",
|
|
266
|
-
|
|
267
|
+
**binary_serialization_to_kwargs(value),
|
|
267
268
|
)
|
|
268
269
|
elif isinstance(value, dict):
|
|
269
270
|
self.communicator.ask_rpc(receiver=self.remote_name, method="set_y_axis", **value)
|
pymodaq/utils/leco/utils.py
CHANGED
|
@@ -1,26 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import subprocess
|
|
2
3
|
import sys
|
|
3
|
-
from typing import Any, Union, get_args
|
|
4
|
-
|
|
4
|
+
from typing import Any, Optional, Union, get_args, TypeVar
|
|
5
|
+
from pymodaq_data import data
|
|
6
|
+
from pymodaq.utils import data
|
|
5
7
|
# import also the DeSerializer for easier imports in dependents
|
|
6
|
-
from
|
|
8
|
+
from pymodaq_utils.serialize.serializer_legacy import Serializer, DeSerializer, SerializableFactory
|
|
9
|
+
# type: ignore # noqa
|
|
7
10
|
from pymodaq_utils.logger import set_logger
|
|
8
11
|
|
|
9
12
|
|
|
10
13
|
logger = set_logger('leco_utils')
|
|
11
|
-
|
|
14
|
+
ser_factory = SerializableFactory()
|
|
12
15
|
JSON_TYPES = Union[str, int, float]
|
|
13
16
|
|
|
17
|
+
SERIALIZABLE = ser_factory.get_serializables()
|
|
18
|
+
|
|
14
19
|
|
|
15
20
|
def serialize_object(pymodaq_object: Union[SERIALIZABLE, Any]) -> Union[str, Any]:
|
|
16
21
|
"""Serialize a pymodaq object, if it is not JSON compatible."""
|
|
17
22
|
if isinstance(pymodaq_object, get_args(JSON_TYPES)):
|
|
18
23
|
return pymodaq_object
|
|
24
|
+
else:
|
|
25
|
+
return Serializer(pymodaq_object).to_b64_string() # will raise a proper error if the object
|
|
26
|
+
#is not serializable
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def binary_serialization(
|
|
30
|
+
pymodaq_object: Union[SERIALIZABLE, Any],
|
|
31
|
+
) -> tuple[Optional[Any], Optional[list[bytes]]]:
|
|
32
|
+
"""Serialize (binary) a pymodaq object, if it is not JSON compatible."""
|
|
33
|
+
if isinstance(pymodaq_object, get_args(JSON_TYPES)):
|
|
34
|
+
return pymodaq_object, None
|
|
19
35
|
elif isinstance(pymodaq_object, get_args(SERIALIZABLE)):
|
|
20
|
-
return Serializer(pymodaq_object).
|
|
36
|
+
return None, [Serializer(pymodaq_object).to_bytes()]
|
|
21
37
|
else:
|
|
22
|
-
raise ValueError(
|
|
23
|
-
|
|
38
|
+
raise ValueError(
|
|
39
|
+
f"{pymodaq_object} of type '{type(pymodaq_object).__name__}' is neither "
|
|
40
|
+
"JSON serializable, nor via PyMoDAQ."
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def binary_serialization_to_kwargs(
|
|
45
|
+
pymodaq_object: Union[SERIALIZABLE, Any], data_key: str = "data"
|
|
46
|
+
) -> dict[str, Any]:
|
|
47
|
+
"""Create a dictionary of data parameters and of additional payload to send."""
|
|
48
|
+
d, b = binary_serialization(pymodaq_object=pymodaq_object)
|
|
49
|
+
return {data_key: d, "additional_payload": b}
|
|
24
50
|
|
|
25
51
|
|
|
26
52
|
def run_coordinator():
|
|
@@ -39,6 +39,7 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
39
39
|
selected_actuators: list of DAQ_Move
|
|
40
40
|
sublist of actuators
|
|
41
41
|
"""
|
|
42
|
+
settings_name = 'ModulesManagerSettings'
|
|
42
43
|
detectors_changed = Signal(list)
|
|
43
44
|
actuators_changed = Signal(list)
|
|
44
45
|
det_done_signal = Signal(DataToExport) # dte here contains DataWithAxes
|
|
@@ -117,7 +118,7 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
117
118
|
modules = [modules]
|
|
118
119
|
return [mod.title for mod in modules]
|
|
119
120
|
|
|
120
|
-
def get_mods_from_names(self, names, mod='det'):
|
|
121
|
+
def get_mods_from_names(self, names, mod='det') -> List[Union['DAQ_Move', 'DAQ_Viewer']]:
|
|
121
122
|
"""Getter of a list of given modules from their name (title)
|
|
122
123
|
|
|
123
124
|
Parameters
|
|
@@ -172,9 +173,14 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
172
173
|
|
|
173
174
|
@property
|
|
174
175
|
def detectors_all(self):
|
|
175
|
-
"""Get the list of all detectors"""
|
|
176
|
+
"""Get/Set the list of all detectors"""
|
|
176
177
|
return self._detectors
|
|
177
178
|
|
|
179
|
+
@detectors_all.setter
|
|
180
|
+
def detectors_all(self, detectors: List['DAQ_Viewer']):
|
|
181
|
+
self._detectors = detectors
|
|
182
|
+
|
|
183
|
+
|
|
178
184
|
@property
|
|
179
185
|
def actuators(self) -> List['DAQ_Move']:
|
|
180
186
|
"""Get the list of selected actuators"""
|
|
@@ -185,6 +191,10 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
185
191
|
"""Get the list of all actuators"""
|
|
186
192
|
return self._actuators
|
|
187
193
|
|
|
194
|
+
@actuators_all.setter
|
|
195
|
+
def actuators_all(self, actuators: List['DAQ_Move']):
|
|
196
|
+
self._actuators = actuators
|
|
197
|
+
|
|
188
198
|
@property
|
|
189
199
|
def modules(self):
|
|
190
200
|
"""Get the list of all detectors and actuators"""
|
|
@@ -244,11 +254,11 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
244
254
|
elif param.name() == 'actuators':
|
|
245
255
|
self.actuators_changed.emit(param.value()['selected'])
|
|
246
256
|
|
|
247
|
-
def get_det_data_list(self):
|
|
257
|
+
def get_det_data_list(self) -> DataToExport:
|
|
248
258
|
"""Do a snap of selected detectors, to get the list of all the data and processed data"""
|
|
249
259
|
|
|
250
260
|
self.connect_detectors()
|
|
251
|
-
datas: DataToExport = self.
|
|
261
|
+
datas: DataToExport = self.grab_data()
|
|
252
262
|
|
|
253
263
|
data_list0D = datas.get_full_names('data0D')
|
|
254
264
|
data_list1D = datas.get_full_names('data1D')
|
|
@@ -265,6 +275,7 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
265
275
|
dict(all_items=data_listND, selected=[]))
|
|
266
276
|
|
|
267
277
|
self.connect_detectors(False)
|
|
278
|
+
return datas
|
|
268
279
|
|
|
269
280
|
def get_selected_probed_data(self, dim='0D'):
|
|
270
281
|
"""Get the name of selected data names of a given dimensionality
|
|
@@ -276,7 +287,7 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
276
287
|
"""
|
|
277
288
|
return self.settings.child('data_dimensions', f'det_data_list{dim.upper()}').value()['selected']
|
|
278
289
|
|
|
279
|
-
def
|
|
290
|
+
def grab_data(self, **kwargs):
|
|
280
291
|
"""Do a single grab of connected and selected detectors"""
|
|
281
292
|
self.det_done_datas = DataToExport(name=__class__.__name__, control_module='DAQ_Viewer')
|
|
282
293
|
self._received_data = 0
|
|
@@ -300,6 +311,10 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
300
311
|
self.det_done_signal.emit(self.det_done_datas)
|
|
301
312
|
return self.det_done_datas
|
|
302
313
|
|
|
314
|
+
def grab_datas(self, **kwargs):
|
|
315
|
+
""" For back compatibility but use self.grab_data"""
|
|
316
|
+
return self.grab_data(**kwargs)
|
|
317
|
+
|
|
303
318
|
def connect_actuators(self, connect=True, slot=None, signal='move_done'):
|
|
304
319
|
"""Connect the selected actuators signal to a given or default slot
|
|
305
320
|
|
|
@@ -482,11 +497,6 @@ class ModulesManager(QObject, ParameterManager):
|
|
|
482
497
|
self.det_done_flag = True
|
|
483
498
|
self.settings.child('det_done').setValue(self.det_done_flag)
|
|
484
499
|
|
|
485
|
-
# if data.name not in list(self.det_done_datas.keys()):
|
|
486
|
-
# self.det_done_datas[data['name']] = data
|
|
487
|
-
# if len(self.det_done_datas.items()) == len(self.detectors):
|
|
488
|
-
# self.det_done_flag = True
|
|
489
|
-
|
|
490
500
|
|
|
491
501
|
if __name__ == '__main__':
|
|
492
502
|
import sys
|
|
@@ -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',
|
|
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
|
-
|
|
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
|
-
|
|
169
|
-
|
|
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.
|
|
158
|
+
filename_without_extension = self.filename
|
|
178
159
|
|
|
179
160
|
try:
|
|
180
161
|
ioxml.parameter_to_xml_file(self.preset_params,
|
|
181
|
-
|
|
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
|
-
|
|
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
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
81
|
-
|
|
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),
|
|
87
|
+
child = {'title': 'Actuator {:02.0f}'.format(newindex),
|
|
88
|
+
'name': f'{name_prefix}{newindex:02.0f}',
|
|
87
89
|
'type': 'group',
|
|
88
|
-
'removable': True, '
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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 = ['
|
|
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
|
|
|
@@ -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')
|