pymodaq 4.4.4__py3-none-any.whl → 4.4.6__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 +27 -8
- pymodaq/control_modules/move_utility_classes.py +10 -1
- pymodaq/examples/qt_less_standalone_module.py +128 -0
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/setup_plugin.py +1 -0
- pymodaq/utils/data.py +7 -0
- pymodaq/utils/leco/daq_move_LECODirector.py +20 -10
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +11 -6
- pymodaq/utils/leco/pymodaq_listener.py +6 -6
- pymodaq/utils/leco/utils.py +25 -1
- {pymodaq-4.4.4.dist-info → pymodaq-4.4.6.dist-info}/METADATA +2 -2
- {pymodaq-4.4.4.dist-info → pymodaq-4.4.6.dist-info}/RECORD +15 -14
- {pymodaq-4.4.4.dist-info → pymodaq-4.4.6.dist-info}/WHEEL +0 -0
- {pymodaq-4.4.4.dist-info → pymodaq-4.4.6.dist-info}/entry_points.txt +0 -0
- {pymodaq-4.4.4.dist-info → pymodaq-4.4.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -595,14 +595,33 @@ class DAQ_Move(ParameterControlModule):
|
|
|
595
595
|
def units(self, unit: str):
|
|
596
596
|
self.settings.child('move_settings', 'units').setValue(unit)
|
|
597
597
|
if self.ui is not None and config('actuator', 'display_units'):
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
598
|
+
self.ui.set_unit_as_suffix(self.get_unit_to_display(unit))
|
|
599
|
+
|
|
600
|
+
@staticmethod
|
|
601
|
+
def get_unit_to_display(unit: str) -> str:
|
|
602
|
+
""" Get the unit to be displayed in the UI
|
|
603
|
+
|
|
604
|
+
If the controller units are in mm the displayed unit will be m
|
|
605
|
+
because m is the base unit, then the user could ask for mm, km, µm...
|
|
606
|
+
only issue is when the usual displayed unit is not the base one, then add cases below
|
|
607
|
+
|
|
608
|
+
Parameters
|
|
609
|
+
----------
|
|
610
|
+
unit: str
|
|
611
|
+
|
|
612
|
+
Returns
|
|
613
|
+
-------
|
|
614
|
+
str: the unit to be displayed on the ui
|
|
615
|
+
"""
|
|
616
|
+
if ('°' in unit or 'degree' in unit) and not '°C' in unit:
|
|
617
|
+
# special cas as pint base unit for angles are radians
|
|
618
|
+
return '°'
|
|
619
|
+
elif 'W' in unit or 'watt' in unit:
|
|
620
|
+
return 'W'
|
|
621
|
+
elif '°C' in unit or 'Celsius' in unit:
|
|
622
|
+
return '°C'
|
|
623
|
+
else:
|
|
624
|
+
return str(Q_(1, unit).to_base_units().units)
|
|
606
625
|
|
|
607
626
|
def update_settings(self):
|
|
608
627
|
|
|
@@ -25,6 +25,7 @@ from pymodaq.utils.enums import BaseEnum, enum_checker
|
|
|
25
25
|
from pymodaq.utils.tcp_ip.mysocket import Socket
|
|
26
26
|
from pymodaq.utils.tcp_ip.serializer import DeSerializer, Serializer
|
|
27
27
|
from pymodaq import Unit
|
|
28
|
+
from pint.errors import OffsetUnitCalculusError
|
|
28
29
|
|
|
29
30
|
if TYPE_CHECKING:
|
|
30
31
|
from pymodaq.control_modules.daq_move import DAQ_Move_Hardware
|
|
@@ -437,7 +438,8 @@ class DAQ_Move_base(QObject):
|
|
|
437
438
|
QtWidgets.QApplication.processEvents()
|
|
438
439
|
self.axis_unit = self.axis_unit
|
|
439
440
|
self.settings.child('epsilon').setValue(self.epsilon)
|
|
440
|
-
|
|
441
|
+
if self.controller is not None:
|
|
442
|
+
self._current_value = self.get_actuator_value()
|
|
441
443
|
|
|
442
444
|
@property
|
|
443
445
|
def axis_names(self) -> Union[List, Dict]:
|
|
@@ -728,6 +730,13 @@ class DAQ_Move_base(QObject):
|
|
|
728
730
|
epsilon_calculated = abs(self._current_value.value() - self._target_value.value())
|
|
729
731
|
logger.warning(f'Unit issue when calculating epsilon, units are not compatible between'
|
|
730
732
|
f'target and current values')
|
|
733
|
+
except OffsetUnitCalculusError as e:
|
|
734
|
+
if '°C' in self.axis_unit or 'celcius' in self.axis_unit.lower():
|
|
735
|
+
epsilon_calculated = (
|
|
736
|
+
self._current_value.to_base_units() -
|
|
737
|
+
self._target_value.to_base_units()).abs().value()
|
|
738
|
+
else:
|
|
739
|
+
raise e
|
|
731
740
|
|
|
732
741
|
return (epsilon_calculated < self.epsilon) and self.user_condition_to_reach_target()
|
|
733
742
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example how to create an actuator or detector module, which does not require Qt, nor any GUI functionality.
|
|
3
|
+
|
|
4
|
+
You can connect to this qtless module with a PyMoDAQ LECODirector module (the detector or actuator version, both are preinstalled),
|
|
5
|
+
as if it were any pymodaq module.
|
|
6
|
+
|
|
7
|
+
This example works best with an Actuator Director Module as it has fake movements, but does not return any detector value.
|
|
8
|
+
In this example, the name is "qt_less" (defined in the final if clause), which you have to give as the "actor" argument to the Director module.
|
|
9
|
+
|
|
10
|
+
Add any code in the methods defined below, for example instrument access and execute the file.
|
|
11
|
+
For remote control, you need to start a Coordinator, as described for remote control via LECO.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from time import sleep
|
|
16
|
+
from typing import List, Union
|
|
17
|
+
|
|
18
|
+
from pyleco.utils.listener import Listener
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class QtLessModule:
|
|
22
|
+
"""Some module doing things without Qt.
|
|
23
|
+
|
|
24
|
+
You can run an instance of this class anywhere in your LECO network.
|
|
25
|
+
Then you can control this instance with a PyMoDAQ LECODirectorModule (in mock modules) as if it were a PyMoDAQ module.
|
|
26
|
+
|
|
27
|
+
Just add any logic you wish to the methods below.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, name: str, host: str = "localhost", **kwargs) -> None:
|
|
31
|
+
super().__init__()
|
|
32
|
+
self.listener = Listener(name=name, host=host, timeout=1, **kwargs)
|
|
33
|
+
self._fake_position = 0
|
|
34
|
+
self.start_listen()
|
|
35
|
+
self._stored = []
|
|
36
|
+
|
|
37
|
+
def start_listen(self) -> None:
|
|
38
|
+
"""Start to listen on incoming commands."""
|
|
39
|
+
self.listener.start_listen()
|
|
40
|
+
self.communicator = self.listener.get_communicator()
|
|
41
|
+
self.register_rpc_methods()
|
|
42
|
+
|
|
43
|
+
def register_rpc_methods(self) -> None:
|
|
44
|
+
"""Make the following methods available via LECO."""
|
|
45
|
+
register_rpc_method = self.communicator.register_rpc_method
|
|
46
|
+
register_rpc_method(self.set_info)
|
|
47
|
+
register_rpc_method(self.send_data)
|
|
48
|
+
register_rpc_method(self.move_abs)
|
|
49
|
+
register_rpc_method(self.move_rel)
|
|
50
|
+
register_rpc_method(self.move_home)
|
|
51
|
+
register_rpc_method(self.get_actuator_value)
|
|
52
|
+
register_rpc_method(self.stop_motion)
|
|
53
|
+
register_rpc_method(self.set_remote_name)
|
|
54
|
+
|
|
55
|
+
def stop_listen(self) -> None:
|
|
56
|
+
"""Stop to listen on incoming commands."""
|
|
57
|
+
self.listener.stop_listen()
|
|
58
|
+
|
|
59
|
+
# smethods for being remote controlled
|
|
60
|
+
# these methods are executed and cannot talk to the controlling module directly.
|
|
61
|
+
# if you need to send a response (for example with a value) you have to store the information and
|
|
62
|
+
# send it after these methods have been executed.
|
|
63
|
+
def set_remote_name(self, name: str) -> None:
|
|
64
|
+
"""Define what the name of the remote for answers is."""
|
|
65
|
+
self.remote_name = name
|
|
66
|
+
|
|
67
|
+
# generic commands
|
|
68
|
+
def set_info(self, path: List[str], param_dict_str: str) -> None:
|
|
69
|
+
print("set_info", path, param_dict_str)
|
|
70
|
+
|
|
71
|
+
# detector commands
|
|
72
|
+
def send_data(self, grabber_type: str = "") -> None:
|
|
73
|
+
print("send_data")
|
|
74
|
+
|
|
75
|
+
# actuator commands
|
|
76
|
+
def move_abs(self, position: Union[float, str]) -> None:
|
|
77
|
+
print("move_abs", position)
|
|
78
|
+
self._fake_position = float(position)
|
|
79
|
+
|
|
80
|
+
def move_rel(self, position: Union[float, str]) -> None:
|
|
81
|
+
print("move_rel", position)
|
|
82
|
+
self._fake_position += float(position)
|
|
83
|
+
|
|
84
|
+
def move_home(self) -> None:
|
|
85
|
+
self._fake_position = 0
|
|
86
|
+
print("move_home")
|
|
87
|
+
|
|
88
|
+
def get_actuator_value(self) -> None:
|
|
89
|
+
"""Request that the actuator value is sent later on."""
|
|
90
|
+
# according to DAQ_Move, this supersedes "check_position"
|
|
91
|
+
print("get_actuator_value")
|
|
92
|
+
# send the actuator position after this method has finished execution.
|
|
93
|
+
# this method sends the result to the controlling control module.
|
|
94
|
+
self.send_later(
|
|
95
|
+
receiver=self.remote_name,
|
|
96
|
+
method="set_position",
|
|
97
|
+
position=self._fake_position,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def stop_motion(self,) -> None:
|
|
101
|
+
# not implemented in DAQ_Move!
|
|
102
|
+
print("stop_motion")
|
|
103
|
+
|
|
104
|
+
# end of methods for being remote controlled
|
|
105
|
+
|
|
106
|
+
def send_later(self, receiver, method, **kwargs):
|
|
107
|
+
"""Store information to send it later."""
|
|
108
|
+
self._stored.append((receiver, method, kwargs))
|
|
109
|
+
|
|
110
|
+
def send_stored(self):
|
|
111
|
+
"""Send messages stored for later sending."""
|
|
112
|
+
while self._stored:
|
|
113
|
+
receiver, method, kwargs = self._stored.pop()
|
|
114
|
+
self.communicator.ask_rpc(receiver=receiver, method=method, **kwargs)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
print("listening endlessly as 'qt_less'")
|
|
119
|
+
log = logging.getLogger()
|
|
120
|
+
log.addHandler(logging.StreamHandler())
|
|
121
|
+
# log.setLevel(logging.DEBUG)
|
|
122
|
+
m = QtLessModule("qt_less")
|
|
123
|
+
try:
|
|
124
|
+
while True:
|
|
125
|
+
sleep(0.1)
|
|
126
|
+
m.send_stored()
|
|
127
|
+
except KeyboardInterrupt:
|
|
128
|
+
m.stop_listen()
|
pymodaq/resources/VERSION
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
version = '4.4.
|
|
1
|
+
version = '4.4.6'
|
|
2
2
|
|
|
@@ -23,6 +23,7 @@ def setup(path: Path):
|
|
|
23
23
|
name=PLUGIN_NAME,
|
|
24
24
|
description=config['plugin-info']['description'],
|
|
25
25
|
long_description=long_description,
|
|
26
|
+
long_description_content_type='text/x-rst',
|
|
26
27
|
license=config['plugin-info']['license'],
|
|
27
28
|
url=config['plugin-info']['package-url'],
|
|
28
29
|
author=config['plugin-info']['author'],
|
pymodaq/utils/data.py
CHANGED
|
@@ -648,6 +648,13 @@ class DataBase(DataLowLevel):
|
|
|
648
648
|
""" Change immediately the units to whatever else. Use this with care!"""
|
|
649
649
|
self._units = units
|
|
650
650
|
|
|
651
|
+
def to_base_units(self):
|
|
652
|
+
dwa = self.deepcopy()
|
|
653
|
+
data_quantities = [quantity.to_base_units() for quantity in self.quantities]
|
|
654
|
+
dwa.data = [quantity.magnitude for quantity in data_quantities]
|
|
655
|
+
dwa.force_units(str(data_quantities[0].units))
|
|
656
|
+
return dwa
|
|
657
|
+
|
|
651
658
|
def units_as(self, units: str, inplace=True) -> 'DataBase':
|
|
652
659
|
""" Set the object units to the new one (if possible)
|
|
653
660
|
|
|
@@ -55,11 +55,14 @@ class DAQ_Move_LECODirector(LECODirector, DAQ_Move_base):
|
|
|
55
55
|
params_state=params_state, **kwargs)
|
|
56
56
|
self.register_rpc_methods((
|
|
57
57
|
self.set_info,
|
|
58
|
+
))
|
|
59
|
+
for method in (
|
|
58
60
|
self.set_position,
|
|
59
61
|
self.set_move_done,
|
|
60
62
|
self.set_x_axis,
|
|
61
63
|
self.set_y_axis,
|
|
62
|
-
)
|
|
64
|
+
):
|
|
65
|
+
self.listener.register_binary_rpc_method(method, accept_binary_input=True)
|
|
63
66
|
|
|
64
67
|
# copied, I think it is good:
|
|
65
68
|
self.settings.child('bounds').hide()
|
|
@@ -143,22 +146,29 @@ class DAQ_Move_LECODirector(LECODirector, DAQ_Move_base):
|
|
|
143
146
|
self.controller.stop_motion()
|
|
144
147
|
|
|
145
148
|
# Methods accessible via remote calls
|
|
146
|
-
def _set_position_value(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
def _set_position_value(
|
|
150
|
+
self, position: Union[str, float, None], additional_payload=None
|
|
151
|
+
) -> DataActuator:
|
|
152
|
+
if position:
|
|
153
|
+
if isinstance(position, str):
|
|
154
|
+
deserializer = DeSerializer.from_b64_string(position)
|
|
155
|
+
pos = deserializer.dwa_deserialization()
|
|
156
|
+
else:
|
|
157
|
+
pos = DataActuator(data=position)
|
|
158
|
+
elif additional_payload is not None:
|
|
159
|
+
pos = DeSerializer(additional_payload[0]).dwa_deserialization()
|
|
150
160
|
else:
|
|
151
|
-
|
|
161
|
+
raise ValueError("No position given")
|
|
152
162
|
pos = self.get_position_with_scaling(pos) # type: ignore
|
|
153
163
|
self._current_value = pos
|
|
154
164
|
return pos
|
|
155
165
|
|
|
156
|
-
def set_position(self, position: Union[str, float]) -> None:
|
|
157
|
-
pos = self._set_position_value(position=position)
|
|
166
|
+
def set_position(self, position: Union[str, float, None], additional_payload=None) -> None:
|
|
167
|
+
pos = self._set_position_value(position=position, additional_payload=additional_payload)
|
|
158
168
|
self.emit_status(ThreadCommand('get_actuator_value', [pos]))
|
|
159
169
|
|
|
160
|
-
def set_move_done(self, position: Union[str, float]) -> None:
|
|
161
|
-
pos = self._set_position_value(position=position)
|
|
170
|
+
def set_move_done(self, position: Union[str, float, None], additional_payload=None) -> None:
|
|
171
|
+
pos = self._set_position_value(position=position, additional_payload=additional_payload)
|
|
162
172
|
self.emit_status(ThreadCommand('move_done', [pos]))
|
|
163
173
|
|
|
164
174
|
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
|
|
|
@@ -37,8 +37,11 @@ class DAQ_xDViewer_LECODirector(LECODirector, DAQ_Viewer_base):
|
|
|
37
37
|
self.register_rpc_methods((
|
|
38
38
|
self.set_x_axis,
|
|
39
39
|
self.set_y_axis,
|
|
40
|
-
self.set_data,
|
|
41
40
|
))
|
|
41
|
+
for method in (
|
|
42
|
+
self.set_data,
|
|
43
|
+
):
|
|
44
|
+
self.listener.register_binary_rpc_method(method, accept_binary_input=True)
|
|
42
45
|
|
|
43
46
|
self.client_type = "GRABBER"
|
|
44
47
|
self.x_axis = None
|
|
@@ -150,7 +153,7 @@ class DAQ_xDViewer_LECODirector(LECODirector, DAQ_Viewer_base):
|
|
|
150
153
|
self.y_axis = dict(data=data, label=label, units=units)
|
|
151
154
|
self.emit_y_axis()
|
|
152
155
|
|
|
153
|
-
def set_data(self, data: Union[list, str]) -> None:
|
|
156
|
+
def set_data(self, data: Union[list, str, None], 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__':
|
|
@@ -17,7 +17,7 @@ from qtpy.QtCore import QObject, Signal # type: ignore
|
|
|
17
17
|
from pymodaq.utils.daq_utils import ThreadCommand
|
|
18
18
|
from pymodaq.utils.parameter import ioxml
|
|
19
19
|
from pymodaq.utils.tcp_ip.serializer import DataWithAxes, SERIALIZABLE, DeSerializer
|
|
20
|
-
from pymodaq.utils.leco.utils import
|
|
20
|
+
from pymodaq.utils.leco.utils import binary_serialization_to_kwargs
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class LECOClientCommands(StrEnum):
|
|
@@ -220,7 +220,7 @@ class ActorListener(PymodaqListener):
|
|
|
220
220
|
self.communicator.ask_rpc(
|
|
221
221
|
receiver=self.remote_name,
|
|
222
222
|
method="set_data",
|
|
223
|
-
|
|
223
|
+
**binary_serialization_to_kwargs(value),
|
|
224
224
|
)
|
|
225
225
|
|
|
226
226
|
elif command.command == 'send_info':
|
|
@@ -236,14 +236,14 @@ class ActorListener(PymodaqListener):
|
|
|
236
236
|
value = command.attribute[0] # type: ignore
|
|
237
237
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
238
238
|
method="set_position",
|
|
239
|
-
|
|
239
|
+
**binary_serialization_to_kwargs(value, data_key="position"),
|
|
240
240
|
)
|
|
241
241
|
|
|
242
242
|
elif command.command == LECOMoveCommands.MOVE_DONE:
|
|
243
243
|
value = command.attribute[0] # type: ignore
|
|
244
244
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
245
245
|
method="set_move_done",
|
|
246
|
-
|
|
246
|
+
**binary_serialization_to_kwargs(value, data_key="position"),
|
|
247
247
|
)
|
|
248
248
|
|
|
249
249
|
elif command.command == 'x_axis':
|
|
@@ -251,7 +251,7 @@ class ActorListener(PymodaqListener):
|
|
|
251
251
|
if isinstance(value, SERIALIZABLE):
|
|
252
252
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
253
253
|
method="set_x_axis",
|
|
254
|
-
|
|
254
|
+
**binary_serialization_to_kwargs(value),
|
|
255
255
|
)
|
|
256
256
|
elif isinstance(value, dict):
|
|
257
257
|
self.communicator.ask_rpc(receiver=self.remote_name, method="set_x_axis", **value)
|
|
@@ -263,7 +263,7 @@ class ActorListener(PymodaqListener):
|
|
|
263
263
|
if isinstance(value, SERIALIZABLE):
|
|
264
264
|
self.communicator.ask_rpc(receiver=self.remote_name,
|
|
265
265
|
method="set_y_axis",
|
|
266
|
-
|
|
266
|
+
**binary_serialization_to_kwargs(value),
|
|
267
267
|
)
|
|
268
268
|
elif isinstance(value, dict):
|
|
269
269
|
self.communicator.ask_rpc(receiver=self.remote_name, method="set_y_axis", **value)
|
pymodaq/utils/leco/utils.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import subprocess
|
|
2
3
|
import sys
|
|
3
|
-
from typing import Any, Union, get_args
|
|
4
|
+
from typing import Any, Optional, Union, get_args
|
|
4
5
|
|
|
5
6
|
# import also the DeSerializer for easier imports in dependents
|
|
6
7
|
from pymodaq.utils.tcp_ip.serializer import SERIALIZABLE, Serializer, DeSerializer # type: ignore # noqa
|
|
@@ -23,6 +24,29 @@ def serialize_object(pymodaq_object: Union[SERIALIZABLE, Any]) -> Union[str, Any
|
|
|
23
24
|
"JSON serializable, nor via PyMoDAQ.")
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
def binary_serialization(
|
|
28
|
+
pymodaq_object: Union[SERIALIZABLE, Any],
|
|
29
|
+
) -> tuple[Optional[Any], Optional[list[bytes]]]:
|
|
30
|
+
"""Serialize (binary) a pymodaq object, if it is not JSON compatible."""
|
|
31
|
+
if isinstance(pymodaq_object, get_args(JSON_TYPES)):
|
|
32
|
+
return pymodaq_object, None
|
|
33
|
+
elif isinstance(pymodaq_object, get_args(SERIALIZABLE)):
|
|
34
|
+
return None, [Serializer(pymodaq_object).to_bytes()]
|
|
35
|
+
else:
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"{pymodaq_object} of type '{type(pymodaq_object).__name__}' is neither "
|
|
38
|
+
"JSON serializable, nor via PyMoDAQ."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def binary_serialization_to_kwargs(
|
|
43
|
+
pymodaq_object: Union[SERIALIZABLE, Any], data_key: str = "data"
|
|
44
|
+
) -> dict[str, Any]:
|
|
45
|
+
"""Create a dictionary of data parameters and of additional payload to send."""
|
|
46
|
+
d, b = binary_serialization(pymodaq_object=pymodaq_object)
|
|
47
|
+
return {data_key: d, "additional_payload": b}
|
|
48
|
+
|
|
49
|
+
|
|
26
50
|
def run_coordinator():
|
|
27
51
|
command = [sys.executable, '-m', 'pyleco.coordinators.coordinator']
|
|
28
52
|
subprocess.Popen(command)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pymodaq
|
|
3
|
-
Version: 4.4.
|
|
3
|
+
Version: 4.4.6
|
|
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
|
|
@@ -51,7 +51,7 @@ Requires-Dist: multipledispatch
|
|
|
51
51
|
Requires-Dist: numpy<2.0.0
|
|
52
52
|
Requires-Dist: packaging
|
|
53
53
|
Requires-Dist: pint
|
|
54
|
-
Requires-Dist: pyleco; python_version >= '3.8'
|
|
54
|
+
Requires-Dist: pyleco>0.3; python_version >= '3.8'
|
|
55
55
|
Requires-Dist: pymodaq-plugin-manager>=0.0.17
|
|
56
56
|
Requires-Dist: pymodaq-plugins-mock<5.0.0
|
|
57
57
|
Requires-Dist: pyqtgraph>=0.12
|
|
@@ -3,12 +3,12 @@ pymodaq/dashboard.py,sha256=4fbV92erom0yWwqPMtx3KW1q-d6QYflV-EhOZMg24a4,64476
|
|
|
3
3
|
pymodaq/icon.ico,sha256=hOHHfNDENKphQvG1WDleSEYcHukneR2eRFJu8isIlD4,74359
|
|
4
4
|
pymodaq/splash.png,sha256=ow8IECF3tPRUMA4tf2tMu1aRiMaxx91_Y2ckVxkrmF0,53114
|
|
5
5
|
pymodaq/control_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
pymodaq/control_modules/daq_move.py,sha256=
|
|
6
|
+
pymodaq/control_modules/daq_move.py,sha256=0zit9shAo6HAVxkaYdhhuSN-yu8j8T_TLSF6YOaM85Y,37842
|
|
7
7
|
pymodaq/control_modules/daq_move_ui.py,sha256=IbqNAErwXGjKUbYEptvZUz3J8MapNBFIbQnUf9nQrMw,15753
|
|
8
8
|
pymodaq/control_modules/daq_viewer.py,sha256=5CYmdWHGE7sQApeMfdWNV3zbPyoxxYtzFlQ1PaEw4fI,57883
|
|
9
9
|
pymodaq/control_modules/daq_viewer_ui.py,sha256=FWP3jdIOR9vTgYqNaaodteGZ3dwgQ1GdWKrOpOAuSrs,15693
|
|
10
10
|
pymodaq/control_modules/mocks.py,sha256=hh_xSWp9g1UV3NAQVD9Ft9tNWfTsSvKU0OU0trgzP2w,1956
|
|
11
|
-
pymodaq/control_modules/move_utility_classes.py,sha256=
|
|
11
|
+
pymodaq/control_modules/move_utility_classes.py,sha256=PDiPVAfOEAhtTc6MS0oVCy3AL-6KLSxOgYg3c5jctoA,43417
|
|
12
12
|
pymodaq/control_modules/utils.py,sha256=5YdSwq_lFJm7IalYWe_Hn1U4LUoUmo1gedvV9UguU0Y,20016
|
|
13
13
|
pymodaq/control_modules/viewer_utility_classes.py,sha256=OHxwue1t3z2AXyeqNjnwPT2pMc8yXhnqyiWc9IdCI2c,26841
|
|
14
14
|
pymodaq/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -18,6 +18,7 @@ pymodaq/examples/function_plotter.py,sha256=T-VT0Rd3jHP9GcR2h6Nao6lwZE06P8zWUbOl
|
|
|
18
18
|
pymodaq/examples/nonlinearscanner.py,sha256=x0R2_FP0YnuOCCAmYRiAiZ1jfUdRxu5RqIYLyGQMZ0U,3790
|
|
19
19
|
pymodaq/examples/parameter_ex.py,sha256=NmFUvUByNtm3j4leN_MkufQsKlNU8Rx5lmpsVG58IIM,8556
|
|
20
20
|
pymodaq/examples/preset_MockCamera.xml,sha256=quQlMsX6YSoqqc9_9Y-9zu3TDM6Xvnuc2JSWwg9f948,15774
|
|
21
|
+
pymodaq/examples/qt_less_standalone_module.py,sha256=9UD4niVfNXscDVQiOJuuL6lN9PC7Jfp9FwVJ0qz_6Do,4857
|
|
21
22
|
pymodaq/examples/tcp_client.py,sha256=FSdPlb3R_rxxNIqPqHVU8PxJzNZeFk_93l4TqsB5SnA,2584
|
|
22
23
|
pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.aliases,sha256=t0eKH9Uq_AMk4wQ-6Pm5mKUjGcCvfT9GtvMsvDhkCUk,47
|
|
23
24
|
pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvlps,sha256=VZHH96rKSnRYKeCAXUmKI3vQOX8Wz53FYCF2yXuqnaU,84
|
|
@@ -58,11 +59,11 @@ pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py,sha256=1u7hWDaiwsZ
|
|
|
58
59
|
pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui,sha256=PyzbCWPMkh5oIYYteZczXyWMeHKW9EJmM1QlzXhnyTk,7037
|
|
59
60
|
pymodaq/post_treatment/daq_measurement/daq_measurement_main.py,sha256=CAKwcWMOD86aXB8mbdxOK7e8nZRos5d59FzDtqK1QoY,17093
|
|
60
61
|
pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat,sha256=e1tu2A67MS9fk3jhriF6saQgRxWIucIvNW92iWXFP6E,164
|
|
61
|
-
pymodaq/resources/VERSION,sha256=
|
|
62
|
+
pymodaq/resources/VERSION,sha256=WLq0vLL18vLMV1jwQsziDmyw7JVoEVuWAB0pDGzYEvM,19
|
|
62
63
|
pymodaq/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
64
|
pymodaq/resources/config_template.toml,sha256=d3pofgIK5FxaRMELAI1qEsRcMD3GlYd87zZjDj9G9m0,3210
|
|
64
65
|
pymodaq/resources/preset_default.xml,sha256=Dt8iWLwPPOPtcG00JCVP-mh-G7KC6B0YN8hd8RQdnNI,27256
|
|
65
|
-
pymodaq/resources/setup_plugin.py,sha256=
|
|
66
|
+
pymodaq/resources/setup_plugin.py,sha256=jvMuSp4UxGaPUe9uPUvHg9DrdwyFakG6_sFy_zXb1f8,3182
|
|
66
67
|
pymodaq/resources/triangulation_data.npy,sha256=Dzq6eE8f_i7Woloy1iUn6N1OfVdBZ4WnK4J4SCoqXso,9320
|
|
67
68
|
pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat,sha256=gqBmrc6Cfzn7wIZQtzgcglKRQ8zLXLW9Xt8LWxkJdw0,205
|
|
68
69
|
pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc,sha256=S99847o7hvKYOWa9lR3qErMHwcjhjYPEduoq2ylCn4I,10123
|
|
@@ -311,7 +312,7 @@ pymodaq/utils/chrono_timer.py,sha256=rwX8apS8B-IKhA0Cp2H9tLz0BRN7G3Pg5ptozvd3MKM
|
|
|
311
312
|
pymodaq/utils/config.py,sha256=0QqoBJC4ECuIeh1UsvUQqhxkKl7Vfgi4iERp-6qNWAc,16202
|
|
312
313
|
pymodaq/utils/conftests.py,sha256=3Ak8WEpa3EhAp73Yb1LLq8YFONhPqiL7gG9eSDIoTNc,58
|
|
313
314
|
pymodaq/utils/daq_utils.py,sha256=0jTrbT0aaZr3KaTgeDicmK9FbVnu3iaWBmNHnNJpr3A,28050
|
|
314
|
-
pymodaq/utils/data.py,sha256=
|
|
315
|
+
pymodaq/utils/data.py,sha256=rasOk1-2o8fJHE_zm7ygrWXL7cBOHJOgwWMZhbVG7z0,111863
|
|
315
316
|
pymodaq/utils/enums.py,sha256=wpRipioUJkKcEfoaY2NrDQ2WhGxZTZiZoJty5f2Ljpc,2236
|
|
316
317
|
pymodaq/utils/exceptions.py,sha256=wLO6VlofzfwWkOOWMN2B-3NEWMfpgygyeEdakIx_rAs,668
|
|
317
318
|
pymodaq/utils/factory.py,sha256=QLqAPFnTZ93eUpmAAIr7kESDk2enD57RNSuFUsjxE4E,2311
|
|
@@ -358,13 +359,13 @@ pymodaq/utils/h5modules/exporters/base.py,sha256=hGX2teIMO03QB0qBGTP4rzeXbZrQcVL
|
|
|
358
359
|
pymodaq/utils/h5modules/exporters/flimj.py,sha256=z44C30KlAbaPmjnS5inYophnA18LwwqZOa1UMLEi4Tw,2361
|
|
359
360
|
pymodaq/utils/h5modules/exporters/hyperspy.py,sha256=rheeVJQO0BAF606D_0S_j8huzOLzZfkUAp0OdJEnUz4,6517
|
|
360
361
|
pymodaq/utils/leco/__init__.py,sha256=wxgCC-0eragO_REWDMp-2zg9kK5l_W9oO68dtRYdoKA,878
|
|
361
|
-
pymodaq/utils/leco/daq_move_LECODirector.py,sha256=
|
|
362
|
-
pymodaq/utils/leco/daq_xDviewer_LECODirector.py,sha256=
|
|
362
|
+
pymodaq/utils/leco/daq_move_LECODirector.py,sha256=neYq17utjIm_5KzJkglABd_iL0Ltolcri9oMcBDs-I8,6915
|
|
363
|
+
pymodaq/utils/leco/daq_xDviewer_LECODirector.py,sha256=q6r-oJFMWqc0AOlRQShxX1w64LgnVVSyFzh3sSYUFV4,6310
|
|
363
364
|
pymodaq/utils/leco/desktop.ini,sha256=2zopClaSQqdFfIsC8CGo2Oc-14x9h1gV0-fUrDtLFmA,82
|
|
364
365
|
pymodaq/utils/leco/director_utils.py,sha256=f_rzS6p7VxfWvgm36JRgBHphqYMZrw3gqsadgF9ZtIg,2109
|
|
365
366
|
pymodaq/utils/leco/leco_director.py,sha256=WPsZB6oJIkDJIqtagbeuErfpGB-ENF-s0rtoj_EGVdM,3054
|
|
366
|
-
pymodaq/utils/leco/pymodaq_listener.py,sha256=
|
|
367
|
-
pymodaq/utils/leco/utils.py,sha256=
|
|
367
|
+
pymodaq/utils/leco/pymodaq_listener.py,sha256=OmYC6c3OYjqcT7M881b-g8lXIua2Pq-YYv4X_TuxaPM,10802
|
|
368
|
+
pymodaq/utils/leco/utils.py,sha256=jCHhco89uG9UA-t9LpaEuyZQMQW5XQP_t0URcvqLDNU,2362
|
|
368
369
|
pymodaq/utils/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
369
370
|
pymodaq/utils/managers/action_manager.py,sha256=v99NuRq7uT_PNTAsqbUyoWyDGUzhlP6dYtdAO30_cbc,17756
|
|
370
371
|
pymodaq/utils/managers/batchscan_manager.py,sha256=jcL08YvFafX5kiy03BV1_6obt2Xogiby5pvTKeN8_ho,13905
|
|
@@ -438,8 +439,8 @@ pymodaq/utils/tcp_ip/__init__.py,sha256=1e_EK0AgvdoLAD_CSGGEaITZdy6OWCO7ih9IAIp7
|
|
|
438
439
|
pymodaq/utils/tcp_ip/mysocket.py,sha256=StAWj8dzHeMnbLj68Sel81uWFy-YkKVNRnVf7gXrESI,3452
|
|
439
440
|
pymodaq/utils/tcp_ip/serializer.py,sha256=htVQCE4saRBMeIcseEyxTt5G58A341m6OGkaJUA34Wk,27766
|
|
440
441
|
pymodaq/utils/tcp_ip/tcp_server_client.py,sha256=xIMTNgVW_rKK0yTi4FDNFLf85-Akb27Jz2LdrvOrP68,30660
|
|
441
|
-
pymodaq-4.4.
|
|
442
|
-
pymodaq-4.4.
|
|
443
|
-
pymodaq-4.4.
|
|
444
|
-
pymodaq-4.4.
|
|
445
|
-
pymodaq-4.4.
|
|
442
|
+
pymodaq-4.4.6.dist-info/METADATA,sha256=mJV-zKqrF_yCIPzo_-brHM2vJqBIdptzQPzVJ8qmIbM,7627
|
|
443
|
+
pymodaq-4.4.6.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
444
|
+
pymodaq-4.4.6.dist-info/entry_points.txt,sha256=RAzdYNjvUT28I2eiCKki_g2NzXq0woWxhev6lwzwRv8,348
|
|
445
|
+
pymodaq-4.4.6.dist-info/licenses/LICENSE,sha256=VKOejxexXAe3XwfhAhcFGqeXQ12irxVHdeAojZwFEI8,1108
|
|
446
|
+
pymodaq-4.4.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|