pymodaq 5.0.5__py3-none-any.whl → 5.1.0a0__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/control_modules/daq_move.py +77 -64
- pymodaq/control_modules/daq_move_ui.py +16 -15
- pymodaq/control_modules/daq_viewer.py +95 -87
- pymodaq/control_modules/daq_viewer_ui.py +22 -23
- pymodaq/control_modules/mocks.py +2 -2
- pymodaq/control_modules/move_utility_classes.py +28 -19
- pymodaq/control_modules/thread_commands.py +138 -0
- pymodaq/control_modules/utils.py +88 -20
- pymodaq/control_modules/viewer_utility_classes.py +8 -17
- pymodaq/dashboard.py +90 -27
- pymodaq/examples/qt_less_standalone_module.py +48 -11
- pymodaq/extensions/__init__.py +7 -3
- pymodaq/extensions/adaptive/__init__.py +2 -0
- pymodaq/extensions/adaptive/adaptive_optimization.py +159 -0
- pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
- pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +86 -0
- pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
- pymodaq/extensions/adaptive/loss_function/loss_factory.py +106 -0
- pymodaq/extensions/adaptive/utils.py +97 -0
- pymodaq/extensions/bayesian/__init__.py +1 -1
- pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
- pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +71 -0
- pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +86 -0
- pymodaq/extensions/bayesian/bayesian_optimization.py +121 -0
- pymodaq/extensions/bayesian/utils.py +27 -286
- pymodaq/extensions/daq_logger/daq_logger.py +7 -12
- pymodaq/extensions/daq_logger/h5logging.py +1 -1
- pymodaq/extensions/daq_scan.py +18 -47
- pymodaq/extensions/h5browser.py +3 -34
- pymodaq/extensions/optimizers_base/__init__.py +0 -0
- pymodaq/extensions/{bayesian/bayesian_optimisation.py → optimizers_base/optimizer.py} +441 -334
- pymodaq/extensions/optimizers_base/thread_commands.py +20 -0
- pymodaq/extensions/optimizers_base/utils.py +378 -0
- pymodaq/extensions/pid/pid_controller.py +6 -10
- pymodaq/extensions/utils.py +12 -0
- pymodaq/utils/data.py +1 -0
- pymodaq/utils/gui_utils/loader_utils.py +2 -0
- pymodaq/utils/h5modules/module_saving.py +134 -22
- pymodaq/utils/leco/daq_move_LECODirector.py +73 -73
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +36 -84
- pymodaq/utils/leco/director_utils.py +25 -10
- pymodaq/utils/leco/leco_director.py +65 -26
- pymodaq/utils/leco/pymodaq_listener.py +118 -68
- pymodaq/utils/leco/utils.py +24 -24
- pymodaq/utils/managers/modules_manager.py +37 -8
- pymodaq/utils/scanner/scanners/_1d_scanners.py +0 -38
- pymodaq/utils/scanner/scanners/_2d_scanners.py +0 -58
- {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/METADATA +4 -3
- {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/RECORD +52 -38
- {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/entry_points.txt +0 -2
- pymodaq/utils/leco/desktop.ini +0 -2
- {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/WHEEL +0 -0
- {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/licenses/LICENSE +0 -0
|
@@ -10,6 +10,7 @@ import numpy as np
|
|
|
10
10
|
from qtpy import QtWidgets
|
|
11
11
|
from qtpy.QtCore import QObject, Slot, Signal, QTimer
|
|
12
12
|
|
|
13
|
+
|
|
13
14
|
from pymodaq_utils.utils import ThreadCommand, find_keys_from_val
|
|
14
15
|
from pymodaq_utils import config as configmod
|
|
15
16
|
from pymodaq_utils.warnings import deprecation_msg
|
|
@@ -34,6 +35,8 @@ from pymodaq_utils.serialize.serializer_legacy import DeSerializer, Serializer
|
|
|
34
35
|
from pymodaq import Unit
|
|
35
36
|
from pint.errors import OffsetUnitCalculusError
|
|
36
37
|
|
|
38
|
+
from pymodaq.control_modules.thread_commands import ThreadStatus, ThreadStatusMove
|
|
39
|
+
|
|
37
40
|
if TYPE_CHECKING:
|
|
38
41
|
from pymodaq.control_modules.daq_move import DAQ_Move_Hardware
|
|
39
42
|
|
|
@@ -281,7 +284,8 @@ class DAQ_Move_base(QObject):
|
|
|
281
284
|
data_shape = (1, ) # expected shape of the underlying actuator's value (in general a float so shape = (1, ))
|
|
282
285
|
|
|
283
286
|
def __init__(self, parent: Optional['DAQ_Move_Hardware'] = None,
|
|
284
|
-
params_state: Optional[dict] = None
|
|
287
|
+
params_state: Optional[dict] = None,
|
|
288
|
+
**kwargs):
|
|
285
289
|
QObject.__init__(self) # to make sure this is the parent class
|
|
286
290
|
self.move_is_done = False
|
|
287
291
|
self.parent = parent
|
|
@@ -341,7 +345,7 @@ class DAQ_Move_base(QObject):
|
|
|
341
345
|
def axis_unit(self, unit: str):
|
|
342
346
|
self.axis_units[self.axis_index_key] = unit
|
|
343
347
|
self.settings.child('units').setValue(unit)
|
|
344
|
-
self.emit_status(ThreadCommand(
|
|
348
|
+
self.emit_status(ThreadCommand(ThreadStatusMove.UNITS, unit))
|
|
345
349
|
|
|
346
350
|
@property
|
|
347
351
|
def axis_units(self) -> Union[List[str], Dict[str, str]]:
|
|
@@ -610,7 +614,7 @@ class DAQ_Move_base(QObject):
|
|
|
610
614
|
for data_array in position:
|
|
611
615
|
data_array[data_array > self.settings['bounds', 'max_bound']] = self.settings['bounds', 'max_bound']
|
|
612
616
|
data_array[data_array < self.settings['bounds', 'min_bound']] = self.settings['bounds', 'min_bound']
|
|
613
|
-
self.emit_status(ThreadCommand(
|
|
617
|
+
self.emit_status(ThreadCommand(ThreadStatusMove.OUT_OF_BOUNDS, []))
|
|
614
618
|
return position
|
|
615
619
|
|
|
616
620
|
def get_actuator_value(self):
|
|
@@ -657,7 +661,7 @@ class DAQ_Move_base(QObject):
|
|
|
657
661
|
def emit_value(self, pos: DataActuator):
|
|
658
662
|
"""Convenience method to emit the current actuator value back to the UI"""
|
|
659
663
|
|
|
660
|
-
self.emit_status(ThreadCommand(
|
|
664
|
+
self.emit_status(ThreadCommand(ThreadStatusMove.GET_ACTUATOR_VALUE, pos))
|
|
661
665
|
|
|
662
666
|
def commit_settings(self, param: Parameter):
|
|
663
667
|
"""
|
|
@@ -698,7 +702,8 @@ class DAQ_Move_base(QObject):
|
|
|
698
702
|
--------
|
|
699
703
|
DAQ_utils.ThreadCommand, move_done
|
|
700
704
|
"""
|
|
701
|
-
if 'TCPServer'
|
|
705
|
+
if not ('TCPServer' in self.__class__.__name__ or
|
|
706
|
+
'LECODirector' in self.__class__.__name__):
|
|
702
707
|
self.start_time = perf_counter()
|
|
703
708
|
if self.ispolling:
|
|
704
709
|
self.poll_timer.start()
|
|
@@ -768,7 +773,7 @@ class DAQ_Move_base(QObject):
|
|
|
768
773
|
|
|
769
774
|
logger.debug(f'Check move_is_done: {self.move_is_done}')
|
|
770
775
|
if self.move_is_done:
|
|
771
|
-
self.emit_status(ThreadCommand('Move has been stopped', ))
|
|
776
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_STATUS, 'Move has been stopped', ))
|
|
772
777
|
logger.info('Move has been stopped')
|
|
773
778
|
self.current_value = self.get_actuator_value()
|
|
774
779
|
self.emit_value(self._current_value)
|
|
@@ -776,7 +781,7 @@ class DAQ_Move_base(QObject):
|
|
|
776
781
|
|
|
777
782
|
if perf_counter() - self.start_time >= self.settings['timeout']:
|
|
778
783
|
self.poll_timer.stop()
|
|
779
|
-
self.emit_status(ThreadCommand(
|
|
784
|
+
self.emit_status(ThreadCommand(ThreadStatus.RAISE_TIMEOUT, ))
|
|
780
785
|
logger.info('Timeout activated')
|
|
781
786
|
else:
|
|
782
787
|
self.poll_timer.stop()
|
|
@@ -793,17 +798,19 @@ class DAQ_Move_base(QObject):
|
|
|
793
798
|
for param, change, data in changes:
|
|
794
799
|
path = self.settings.childPath(param)
|
|
795
800
|
if change == 'childAdded':
|
|
796
|
-
self.emit_status(ThreadCommand(
|
|
801
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_SETTINGS,
|
|
797
802
|
[self.parent_parameters_path + path, [data[0].saveState(), data[1]],
|
|
798
803
|
change])) # send parameters values/limits back to the GUI. Send kind of a copy back the GUI otherwise the child reference will be the same in both th eUI and the plugin so one of them will be removed
|
|
799
804
|
elif change == 'value' or change == 'limits' or change == 'options':
|
|
800
|
-
self.emit_status(ThreadCommand(
|
|
801
|
-
|
|
805
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_SETTINGS,
|
|
806
|
+
[self.parent_parameters_path + path, data,
|
|
807
|
+
change])) # send parameters values/limits back to the GUI
|
|
802
808
|
elif change == 'parent':
|
|
803
809
|
pass
|
|
804
810
|
elif change == 'limits':
|
|
805
|
-
self.emit_status(ThreadCommand(
|
|
806
|
-
|
|
811
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_SETTINGS,
|
|
812
|
+
[self.parent_parameters_path + path, data,
|
|
813
|
+
change]))
|
|
807
814
|
|
|
808
815
|
def get_position_with_scaling(self, pos: DataActuator) -> DataActuator:
|
|
809
816
|
""" Get the current position from the hardware with scaling conversion.
|
|
@@ -850,12 +857,14 @@ class DAQ_Move_base(QObject):
|
|
|
850
857
|
except ValueError:
|
|
851
858
|
apply_settings = False
|
|
852
859
|
elif change == 'parent':
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
if children is not None:
|
|
856
|
-
path = putils.get_param_path(children)
|
|
857
|
-
self.settings.child(*path[1:-1]).removeChild(children)
|
|
860
|
+
try:
|
|
861
|
+
children = putils.get_param_from_name(self.settings, param.name())
|
|
858
862
|
|
|
863
|
+
if children is not None:
|
|
864
|
+
path = putils.get_param_path(children)
|
|
865
|
+
self.settings.child(*path[1:-1]).removeChild(children)
|
|
866
|
+
except IndexError:
|
|
867
|
+
logger.debug(f'Could not remove children from {param.name()}')
|
|
859
868
|
self.settings.sigTreeStateChanged.connect(self.send_param_status)
|
|
860
869
|
if apply_settings:
|
|
861
870
|
self.commit_common_settings(param)
|
|
@@ -915,13 +924,13 @@ class DAQ_Move_TCP_server(DAQ_Move_base, TCPServer):
|
|
|
915
924
|
|
|
916
925
|
pos = self.get_position_with_scaling(pos)
|
|
917
926
|
self._current_value = pos
|
|
918
|
-
self.emit_status(ThreadCommand(
|
|
927
|
+
self.emit_status(ThreadCommand(ThreadStatusMove.GET_ACTUATOR_VALUE, pos))
|
|
919
928
|
|
|
920
929
|
elif command == 'move_done':
|
|
921
930
|
pos = DeSerializer(sock).dwa_deserialization()
|
|
922
931
|
pos = self.get_position_with_scaling(pos)
|
|
923
932
|
self._current_value = pos
|
|
924
|
-
self.emit_status(ThreadCommand(
|
|
933
|
+
self.emit_status(ThreadCommand(ThreadStatusMove.MOVE_DONE, pos))
|
|
925
934
|
else:
|
|
926
935
|
self.send_command(sock, command)
|
|
927
936
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
from pymodaq_utils.enums import StrEnum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ThreadStatus(StrEnum):
|
|
5
|
+
""" Allowed Generic commands sent from a plugin using the method: emit_status
|
|
6
|
+
|
|
7
|
+
Valid both for DAQ_Move and DAQ_Viewer control modules
|
|
8
|
+
|
|
9
|
+
See Also
|
|
10
|
+
--------
|
|
11
|
+
ControlModule.thread_status
|
|
12
|
+
"""
|
|
13
|
+
UPDATE_STATUS = 'update_status'
|
|
14
|
+
CLOSE = 'close'
|
|
15
|
+
UPDATE_SETTINGS = 'update_settings'
|
|
16
|
+
UPDATE_MAIN_SETTINGS = 'update_main_settings'
|
|
17
|
+
UPDATE_UI = 'update_ui'
|
|
18
|
+
RAISE_TIMEOUT = 'raise_timeout'
|
|
19
|
+
SHOW_SPLASH = 'show_splash'
|
|
20
|
+
CLOSE_SPLASH = 'close_splash'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ThreadStatusMove(StrEnum):
|
|
24
|
+
""" Allowed Generic commands sent from a plugin using the method: emit_status
|
|
25
|
+
|
|
26
|
+
Valid only for DAQ_Move control module
|
|
27
|
+
|
|
28
|
+
See Also
|
|
29
|
+
--------
|
|
30
|
+
DAQ_Move.thread_status
|
|
31
|
+
"""
|
|
32
|
+
INI_STAGE = 'ini_stage'
|
|
33
|
+
GET_ACTUATOR_VALUE = 'get_actuator_value'
|
|
34
|
+
MOVE_DONE = 'move_done'
|
|
35
|
+
OUT_OF_BOUNDS = 'outofbounds'
|
|
36
|
+
SET_ALLOWED_VALUES = 'set_allowed_values'
|
|
37
|
+
STOP = 'stop'
|
|
38
|
+
UNITS = 'units'
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ThreadStatusViewer(StrEnum):
|
|
42
|
+
""" Allowed Generic commands sent from a plugin using the method: emit_status
|
|
43
|
+
|
|
44
|
+
Valid only for DAQ_Viewer control module
|
|
45
|
+
|
|
46
|
+
See Also
|
|
47
|
+
--------
|
|
48
|
+
DAQ_Viewer.thread_status
|
|
49
|
+
"""
|
|
50
|
+
INI_DETECTOR = 'ini_detector'
|
|
51
|
+
GRAB = 'grab'
|
|
52
|
+
GRAB_STOPPED = 'grab_stopped'
|
|
53
|
+
INI_LCD = 'init_lcd'
|
|
54
|
+
LCD = 'lcd'
|
|
55
|
+
STOP = 'stop'
|
|
56
|
+
UPDATE_CHANNELS = 'update_channels'
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ControlToHardwareMove(StrEnum):
|
|
61
|
+
""" Allowed commands sent from a DAQ_Move to its DAQ_Move_Hardware in another thread
|
|
62
|
+
using the method: command_hardware
|
|
63
|
+
|
|
64
|
+
Valid only for DAQ_Move command_hardware commands
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
INI_STAGE = 'ini_stage'
|
|
68
|
+
STOP_MOTION = 'stop_motion'
|
|
69
|
+
RESET_STOP_MOTION = 'reset_stop_motion'
|
|
70
|
+
MOVE_ABS = 'move_abs'
|
|
71
|
+
MOVE_REL = 'move_rel'
|
|
72
|
+
MOVE_HOME = 'move_home'
|
|
73
|
+
GET_ACTUATOR_VALUE = 'get_actuator_value'
|
|
74
|
+
CLOSE = 'close'
|
|
75
|
+
|
|
76
|
+
class ControlToHardwareViewer(StrEnum):
|
|
77
|
+
""" Allowed commands sent from a DAQ_Viewer to its DAQ_Detector in another thread
|
|
78
|
+
using the method: command_hardware
|
|
79
|
+
|
|
80
|
+
Valid only for DAQ_Viewer command_hardware commands
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
INI_DETECTOR = 'ini_detector'
|
|
84
|
+
|
|
85
|
+
SINGLE = 'single'
|
|
86
|
+
GRAB = 'grab'
|
|
87
|
+
STOP_GRAB = 'stop_grab'
|
|
88
|
+
STOP_ALL = 'stop_all'
|
|
89
|
+
ROI_SELECT = 'roi_select'
|
|
90
|
+
UPDATE_SCANNER = 'update_scanner' # may be deprecated
|
|
91
|
+
CROSSHAIR = 'crosshair'
|
|
92
|
+
UPDATE_WAIT_TIME = 'update_wait_time'
|
|
93
|
+
CLOSE = 'close'
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class UiToMainMove(StrEnum):
|
|
97
|
+
""" Allowed Commands to be sent from the DAQ_Move_UI to the DAQ_Move
|
|
98
|
+
"""
|
|
99
|
+
INIT = 'init'
|
|
100
|
+
QUIT = 'quit'
|
|
101
|
+
SHOW_LOG = 'show_log'
|
|
102
|
+
SHOW_CONFIG = 'show_config'
|
|
103
|
+
STOP = 'stop'
|
|
104
|
+
|
|
105
|
+
MOVE_ABS = 'move_abs'
|
|
106
|
+
MOVE_REL = 'move_rel'
|
|
107
|
+
|
|
108
|
+
ACTUATOR_CHANGED = 'actuator_changed'
|
|
109
|
+
|
|
110
|
+
GET_VALUE = 'get_value'
|
|
111
|
+
|
|
112
|
+
FIND_HOME = 'find_home'
|
|
113
|
+
REL_VALUE = 'rel_value'
|
|
114
|
+
|
|
115
|
+
LOOP_GET_VALUE = 'loop_get_value'
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class UiToMainViewer(StrEnum):
|
|
119
|
+
""" Allowed Commands to be sent from the DAQ_Viewer_UI to the DAQ_Viewer
|
|
120
|
+
"""
|
|
121
|
+
INIT = 'init'
|
|
122
|
+
QUIT = 'quit'
|
|
123
|
+
SHOW_LOG = 'show_log'
|
|
124
|
+
SHOW_CONFIG = 'show_config'
|
|
125
|
+
STOP = 'stop'
|
|
126
|
+
|
|
127
|
+
SNAP = 'snap'
|
|
128
|
+
GRAB = 'grab'
|
|
129
|
+
SAVE_CURRENT = 'save_current'
|
|
130
|
+
SAVE_NEW = 'save_new'
|
|
131
|
+
OPEN = 'open'
|
|
132
|
+
|
|
133
|
+
DETECTOR_CHANGED = 'detector_changed'
|
|
134
|
+
VIEWERS_CHANGED = 'viewers_changed'
|
|
135
|
+
DAQ_TYPE_CHANGED = 'daq_type_changed'
|
|
136
|
+
|
|
137
|
+
DO_BKG = 'do_bkg'
|
|
138
|
+
TAKE_BKG = 'take_bkg'
|
pymodaq/control_modules/utils.py
CHANGED
|
@@ -5,28 +5,31 @@ Created the 03/10/2022
|
|
|
5
5
|
@author: Sebastien Weber
|
|
6
6
|
"""
|
|
7
7
|
from random import randint
|
|
8
|
-
from typing import Optional, Type
|
|
9
|
-
|
|
8
|
+
from typing import Optional, Type, Union
|
|
10
9
|
from easydict import EasyDict as edict
|
|
11
10
|
|
|
12
11
|
from qtpy import QtCore
|
|
13
12
|
from qtpy.QtCore import Signal, QObject, Qt, Slot, QThread
|
|
14
13
|
|
|
14
|
+
from pymodaq.control_modules.thread_commands import ThreadStatus
|
|
15
15
|
from pymodaq_utils.utils import ThreadCommand, find_dict_in_list_from_key_val
|
|
16
16
|
from pymodaq_utils.config import Config
|
|
17
|
-
from pymodaq_utils.enums import BaseEnum
|
|
17
|
+
from pymodaq_utils.enums import BaseEnum
|
|
18
18
|
from pymodaq_utils.logger import get_base_logger, set_logger, get_module_name
|
|
19
19
|
|
|
20
20
|
from pymodaq_gui.utils.custom_app import CustomApp
|
|
21
21
|
from pymodaq_gui.parameter import Parameter, ioxml
|
|
22
|
+
from pymodaq_gui.parameter.utils import ParameterWithPath
|
|
22
23
|
from pymodaq_gui.managers.parameter_manager import ParameterManager
|
|
23
24
|
from pymodaq_gui.plotting.data_viewers import ViewersEnum
|
|
25
|
+
from pymodaq_gui.h5modules.saving import H5Saver
|
|
24
26
|
|
|
25
27
|
from pymodaq.utils.tcp_ip.tcp_server_client import TCPClient
|
|
26
28
|
from pymodaq.utils.exceptions import DetectorError
|
|
27
29
|
from pymodaq.utils.leco.pymodaq_listener import ActorListener, LECOClientCommands, LECOCommands
|
|
28
30
|
|
|
29
31
|
from pymodaq.utils.daq_utils import get_plugins
|
|
32
|
+
from pymodaq.utils.h5modules.module_saving import DetectorSaver, ActuatorSaver
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
class DAQTypesEnum(BaseEnum):
|
|
@@ -130,12 +133,51 @@ class ControlModule(QObject):
|
|
|
130
133
|
self._send_to_tcpip = False
|
|
131
134
|
self._tcpclient_thread = None
|
|
132
135
|
self._hardware_thread = None
|
|
133
|
-
|
|
136
|
+
|
|
134
137
|
self.plugin_config: Optional[Config] = None
|
|
135
138
|
|
|
139
|
+
self._h5saver: Optional[H5Saver] = None
|
|
140
|
+
self._module_and_data_saver = None
|
|
141
|
+
|
|
136
142
|
def __repr__(self):
|
|
137
143
|
return f'{self.__class__.__name__}: {self.title}'
|
|
138
144
|
|
|
145
|
+
def create_new_file(self, new_file: bool):
|
|
146
|
+
if new_file:
|
|
147
|
+
self.close_file()
|
|
148
|
+
|
|
149
|
+
self.module_and_data_saver.h5saver = self.h5saver
|
|
150
|
+
return True
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def h5saver(self):
|
|
154
|
+
if self._h5saver is None:
|
|
155
|
+
self._h5saver = H5Saver(backend=config('general', 'hdf5_backend'))
|
|
156
|
+
if self._h5saver.h5_file is None:
|
|
157
|
+
self._h5saver.init_file(update_h5=True)
|
|
158
|
+
if not self._h5saver.isopen():
|
|
159
|
+
self._h5saver.init_file(addhoc_file_path=self._h5saver.settings['current_h5_file'])
|
|
160
|
+
return self._h5saver
|
|
161
|
+
|
|
162
|
+
@h5saver.setter
|
|
163
|
+
def h5saver(self, h5saver_temp: H5Saver):
|
|
164
|
+
self._h5saver = h5saver_temp
|
|
165
|
+
|
|
166
|
+
def close_file(self):
|
|
167
|
+
self.h5saver.close_file()
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def module_and_data_saver(self):
|
|
171
|
+
if not self._module_and_data_saver.h5saver.isopen():
|
|
172
|
+
self._module_and_data_saver.h5saver = self.h5saver
|
|
173
|
+
return self._module_and_data_saver
|
|
174
|
+
|
|
175
|
+
@module_and_data_saver.setter
|
|
176
|
+
def module_and_data_saver(self, mod: Union[DetectorSaver, ActuatorSaver]):
|
|
177
|
+
self._module_and_data_saver = mod
|
|
178
|
+
self._module_and_data_saver.h5saver = self.h5saver
|
|
179
|
+
|
|
180
|
+
|
|
139
181
|
def custom_command(self, command: str, **kwargs):
|
|
140
182
|
self.command_hardware.emit(ThreadCommand(command, kwargs))
|
|
141
183
|
|
|
@@ -166,20 +208,17 @@ class ControlModule(QObject):
|
|
|
166
208
|
else:
|
|
167
209
|
self.update_status(status.attribute[0])
|
|
168
210
|
|
|
169
|
-
elif status.command ==
|
|
211
|
+
elif status.command == ThreadStatus.UPDATE_STATUS:
|
|
170
212
|
self.update_status(status.attribute)
|
|
171
213
|
|
|
172
|
-
elif status.command ==
|
|
214
|
+
elif status.command == ThreadStatus.CLOSE:
|
|
173
215
|
try:
|
|
174
216
|
self.update_status(status.attribute[0])
|
|
175
217
|
self._hardware_thread.quit()
|
|
176
|
-
self._hardware_thread.wait()
|
|
177
|
-
|
|
178
|
-
if finished:
|
|
179
|
-
pass
|
|
180
|
-
else:
|
|
181
|
-
print('Thread still running')
|
|
218
|
+
terminated = self._hardware_thread.wait(5000)
|
|
219
|
+
if not terminated:
|
|
182
220
|
self._hardware_thread.terminate()
|
|
221
|
+
self._hardware_thread.wait()
|
|
183
222
|
self.update_status('thread is locked?!', 'log')
|
|
184
223
|
except Exception as e:
|
|
185
224
|
logger.exception(f'Wrong call to the "close" command: \n{str(e)}')
|
|
@@ -187,7 +226,7 @@ class ControlModule(QObject):
|
|
|
187
226
|
self._initialized_state = False
|
|
188
227
|
self.init_signal.emit(self._initialized_state)
|
|
189
228
|
|
|
190
|
-
elif status.command ==
|
|
229
|
+
elif status.command == ThreadStatus.UPDATE_MAIN_SETTINGS:
|
|
191
230
|
# this is a way for the plugins to update main settings of the ui (solely values, limits and options)
|
|
192
231
|
try:
|
|
193
232
|
if status.attribute[2] == 'value':
|
|
@@ -199,7 +238,7 @@ class ControlModule(QObject):
|
|
|
199
238
|
except Exception as e:
|
|
200
239
|
logger.exception(f'Wrong call to the "update_main_settings" command: \n{str(e)}')
|
|
201
240
|
|
|
202
|
-
elif status.command ==
|
|
241
|
+
elif status.command == ThreadStatus.UPDATE_SETTINGS:
|
|
203
242
|
# using this the settings shown in the UI for the plugin reflects the real plugin settings
|
|
204
243
|
try:
|
|
205
244
|
self.settings.sigTreeStateChanged.disconnect(
|
|
@@ -227,7 +266,7 @@ class ControlModule(QObject):
|
|
|
227
266
|
logger.exception(f'Wrong call to the "update_settings" command: \n{str(e)}')
|
|
228
267
|
self.settings.sigTreeStateChanged.connect(self.parameter_tree_changed)
|
|
229
268
|
|
|
230
|
-
elif status.command ==
|
|
269
|
+
elif status.command == ThreadStatus.UPDATE_UI:
|
|
231
270
|
try:
|
|
232
271
|
if self.ui is not None:
|
|
233
272
|
if hasattr(self.ui, status.attribute):
|
|
@@ -236,16 +275,16 @@ class ControlModule(QObject):
|
|
|
236
275
|
except Exception as e:
|
|
237
276
|
logger.info(f'Wrong call to the "update_ui" command: \n{str(e)}')
|
|
238
277
|
|
|
239
|
-
elif status.command ==
|
|
278
|
+
elif status.command == ThreadStatus.RAISE_TIMEOUT:
|
|
240
279
|
self.raise_timeout()
|
|
241
280
|
|
|
242
|
-
elif status.command ==
|
|
281
|
+
elif status.command == ThreadStatus.SHOW_SPLASH:
|
|
243
282
|
self.settings_tree.setEnabled(False)
|
|
244
283
|
self.splash_sc.show()
|
|
245
284
|
self.splash_sc.raise_()
|
|
246
285
|
self.splash_sc.showMessage(status.attribute, color=Qt.white)
|
|
247
286
|
|
|
248
|
-
elif status.command ==
|
|
287
|
+
elif status.command == ThreadStatus.CLOSE_SPLASH:
|
|
249
288
|
self.splash_sc.close()
|
|
250
289
|
self.settings_tree.setEnabled(True)
|
|
251
290
|
|
|
@@ -330,7 +369,7 @@ class ControlModule(QObject):
|
|
|
330
369
|
|
|
331
370
|
return Config()
|
|
332
371
|
|
|
333
|
-
def update_status(self, txt, log=True):
|
|
372
|
+
def update_status(self, txt: str, log=True):
|
|
334
373
|
"""Display a message in the ui status bar and eventually log the message
|
|
335
374
|
|
|
336
375
|
Parameters
|
|
@@ -431,7 +470,9 @@ class ParameterControlModule(ParameterManager, ControlModule):
|
|
|
431
470
|
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value():
|
|
432
471
|
self._command_tcpip.emit(ThreadCommand('send_info', dict(path=path, param=param)))
|
|
433
472
|
if self.settings.child('main_settings', 'leco', 'leco_connected').value():
|
|
434
|
-
self._command_tcpip.emit(
|
|
473
|
+
self._command_tcpip.emit(
|
|
474
|
+
ThreadCommand(LECOCommands.SEND_INFO,
|
|
475
|
+
ParameterWithPath(param, path)))
|
|
435
476
|
|
|
436
477
|
def connect_tcp_ip(self, params_state=None, client_type: str = "GRABBER") -> None:
|
|
437
478
|
"""Init a TCPClient in a separated thread to communicate with a distant TCp/IP Server
|
|
@@ -504,6 +545,33 @@ class ParameterControlModule(ParameterManager, ControlModule):
|
|
|
504
545
|
elif status.command == 'Update_Status':
|
|
505
546
|
self.thread_status(status)
|
|
506
547
|
|
|
548
|
+
elif status.command == 'set_info':
|
|
549
|
+
""" The Director sent a parameter to be updated"""
|
|
550
|
+
path_in_settings = status.attribute.path
|
|
551
|
+
if 'move' in self.__class__.__name__.lower():
|
|
552
|
+
common_param = 'move_settings'
|
|
553
|
+
else:
|
|
554
|
+
common_param = 'detector_settings'
|
|
555
|
+
if common_param in path_in_settings:
|
|
556
|
+
param = self.settings.child(*path_in_settings)
|
|
557
|
+
elif 'settings_client' in path_in_settings:
|
|
558
|
+
param = self.settings.child(common_param, *path_in_settings[1:])
|
|
559
|
+
else:
|
|
560
|
+
param = self.settings.child(common_param, *path_in_settings)
|
|
561
|
+
|
|
562
|
+
param.setValue(status.attribute.parameter.value())
|
|
563
|
+
|
|
564
|
+
elif status.command == LECOCommands.GET_SETTINGS:
|
|
565
|
+
""" The Director requested the content of the actuator settings"""
|
|
566
|
+
if 'move' in self.__class__.__name__.lower():
|
|
567
|
+
common_param = 'move_settings'
|
|
568
|
+
else:
|
|
569
|
+
common_param = 'detector_settings'
|
|
570
|
+
self._command_tcpip.emit(
|
|
571
|
+
ThreadCommand(LECOCommands.SET_SETTINGS,
|
|
572
|
+
ioxml.parameter_to_xml_string(
|
|
573
|
+
self.settings.child(common_param))))
|
|
574
|
+
|
|
507
575
|
else:
|
|
508
576
|
# not handled
|
|
509
577
|
return status
|
|
@@ -18,7 +18,7 @@ from pymodaq_utils.warnings import deprecation_msg
|
|
|
18
18
|
from pymodaq_utils.serialize.mysocket import Socket
|
|
19
19
|
from pymodaq_utils.serialize.serializer_legacy import DeSerializer, Serializer
|
|
20
20
|
from pymodaq_gui.plotting.utils.plot_utils import RoiInfo
|
|
21
|
-
|
|
21
|
+
from pymodaq.control_modules.thread_commands import ThreadStatus, ThreadStatusViewer
|
|
22
22
|
from pymodaq_gui.utils.utils import mkQApp
|
|
23
23
|
|
|
24
24
|
comon_parameters = [{'title': 'Controller Status:', 'name': 'controller_status', 'type': 'list',
|
|
@@ -328,15 +328,6 @@ class DAQ_Viewer_base(QObject):
|
|
|
328
328
|
"""
|
|
329
329
|
pass
|
|
330
330
|
|
|
331
|
-
def get_axis(self):
|
|
332
|
-
"""deprecated"""
|
|
333
|
-
raise DeprecationWarning('get_axis is deprecated add the axes within the DataWithAxes, '
|
|
334
|
-
'DataFromPlugins')
|
|
335
|
-
if self.plugin_type == '1D' or self.plugin_type == '2D':
|
|
336
|
-
self.emit_x_axis()
|
|
337
|
-
|
|
338
|
-
if self.plugin_type == '2D':
|
|
339
|
-
self.emit_y_axis()
|
|
340
331
|
|
|
341
332
|
def emit_status(self, status: ThreadCommand):
|
|
342
333
|
"""
|
|
@@ -400,8 +391,7 @@ class DAQ_Viewer_base(QObject):
|
|
|
400
391
|
|
|
401
392
|
self.commit_settings(param)
|
|
402
393
|
except Exception as e:
|
|
403
|
-
self.emit_status(ThreadCommand(
|
|
404
|
-
|
|
394
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_STATUS, str(e)))
|
|
405
395
|
|
|
406
396
|
|
|
407
397
|
def send_param_status(self, param, changes):
|
|
@@ -423,13 +413,14 @@ class DAQ_Viewer_base(QObject):
|
|
|
423
413
|
path = self.settings.childPath(param)
|
|
424
414
|
if change == 'childAdded':
|
|
425
415
|
# first create a "copy" of the actual parameter and send this "copy", to be restored in the main UI
|
|
426
|
-
self.emit_status(ThreadCommand(
|
|
416
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_SETTINGS,
|
|
427
417
|
[self.parent_parameters_path + path, [data[0].saveState(), data[1]],
|
|
428
418
|
change])) # send parameters values/limits back to the GUI. Send kind of a copy back the GUI otherwise the child reference will be the same in both th eUI and the plugin so one of them will be removed
|
|
429
419
|
|
|
430
420
|
elif change == 'value' or change == 'limits' or change == 'options':
|
|
431
|
-
self.emit_status(ThreadCommand(
|
|
432
|
-
|
|
421
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_SETTINGS,
|
|
422
|
+
[self.parent_parameters_path + path, data,
|
|
423
|
+
change])) # send parameters values/limits back to the GUI
|
|
433
424
|
elif change == 'parent':
|
|
434
425
|
pass
|
|
435
426
|
|
|
@@ -544,7 +535,7 @@ class DAQ_Viewer_TCP_server(DAQ_Viewer_base, TCPServer):
|
|
|
544
535
|
self.send_data(command_sock, data) # to be send to a client
|
|
545
536
|
|
|
546
537
|
except Exception as e:
|
|
547
|
-
self.emit_status(ThreadCommand(
|
|
538
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_STATUS, str(e)))
|
|
548
539
|
|
|
549
540
|
def commit_settings(self, param):
|
|
550
541
|
|
|
@@ -640,7 +631,7 @@ class DAQ_Viewer_TCP_server(DAQ_Viewer_base, TCPServer):
|
|
|
640
631
|
# self.command_server.emit(["process_cmds","Send Data 2D"])
|
|
641
632
|
|
|
642
633
|
except Exception as e:
|
|
643
|
-
self.emit_status(ThreadCommand(
|
|
634
|
+
self.emit_status(ThreadCommand(ThreadStatus.UPDATE_STATUS, str(e)))
|
|
644
635
|
|
|
645
636
|
def stop(self):
|
|
646
637
|
"""
|