pymodaq 4.3.7__py3-none-any.whl → 4.4.2__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 +1 -0
- pymodaq/control_modules/daq_move.py +24 -17
- pymodaq/control_modules/daq_move_ui.py +18 -9
- pymodaq/control_modules/move_utility_classes.py +262 -64
- pymodaq/examples/parameter_ex.py +2 -0
- pymodaq/resources/VERSION +1 -1
- pymodaq/utils/config.py +1 -1
- pymodaq/utils/data.py +34 -7
- pymodaq/utils/gui_utils/loader_utils.py +1 -1
- pymodaq/utils/tcp_ip/serializer.py +5 -1
- {pymodaq-4.3.7.dist-info → pymodaq-4.4.2.dist-info}/METADATA +9 -9
- {pymodaq-4.3.7.dist-info → pymodaq-4.4.2.dist-info}/RECORD +15 -15
- {pymodaq-4.3.7.dist-info → pymodaq-4.4.2.dist-info}/WHEEL +0 -0
- {pymodaq-4.3.7.dist-info → pymodaq-4.4.2.dist-info}/entry_points.txt +0 -0
- {pymodaq-4.3.7.dist-info → pymodaq-4.4.2.dist-info}/licenses/LICENSE +0 -0
pymodaq/__init__.py
CHANGED
|
@@ -23,7 +23,8 @@ from easydict import EasyDict as edict
|
|
|
23
23
|
from pymodaq.utils.logger import set_logger, get_module_name
|
|
24
24
|
from pymodaq.control_modules.utils import ParameterControlModule
|
|
25
25
|
from pymodaq.control_modules.daq_move_ui import DAQ_Move_UI, ThreadCommand
|
|
26
|
-
from pymodaq.control_modules.move_utility_classes import MoveCommand, DAQ_Move_base,
|
|
26
|
+
from pymodaq.control_modules.move_utility_classes import (MoveCommand, DAQ_Move_base,
|
|
27
|
+
DataActuatorType, check_units)
|
|
27
28
|
from pymodaq.control_modules.move_utility_classes import params as daq_move_params
|
|
28
29
|
from pymodaq.utils import daq_utils as utils
|
|
29
30
|
from pymodaq.utils.parameter import utils as putils
|
|
@@ -32,7 +33,8 @@ from pymodaq.utils import config as config_mod
|
|
|
32
33
|
from pymodaq.utils.exceptions import ActuatorError
|
|
33
34
|
from pymodaq.utils.messenger import deprecation_msg
|
|
34
35
|
from pymodaq.utils.h5modules import module_saving
|
|
35
|
-
from pymodaq.utils.data import DataRaw, DataToExport, DataFromPlugins, DataActuator
|
|
36
|
+
from pymodaq.utils.data import (DataRaw, DataToExport, DataFromPlugins, DataActuator, Unit,
|
|
37
|
+
DataUnitError)
|
|
36
38
|
from pymodaq.utils.h5modules.backends import Node
|
|
37
39
|
from pymodaq.utils.parameter import ioxml, Parameter
|
|
38
40
|
|
|
@@ -161,11 +163,13 @@ class DAQ_Move(ParameterControlModule):
|
|
|
161
163
|
self.stop_motion()
|
|
162
164
|
elif cmd.command == 'move_abs':
|
|
163
165
|
data_act: DataActuator = cmd.attribute
|
|
164
|
-
data_act.
|
|
166
|
+
if not Unit(data_act.units).is_compatible_with(self.units) and data_act.units != '':
|
|
167
|
+
data_act.force_units(self.units)
|
|
165
168
|
self.move_abs(data_act)
|
|
166
169
|
elif cmd.command == 'move_rel':
|
|
167
170
|
data_act: DataActuator = cmd.attribute
|
|
168
|
-
data_act.
|
|
171
|
+
if not Unit(data_act.units).is_compatible_with(self.units) and data_act.units != '':
|
|
172
|
+
data_act.force_units(self.units)
|
|
169
173
|
self.move_rel(data_act)
|
|
170
174
|
elif cmd.command == 'show_log':
|
|
171
175
|
self.show_log()
|
|
@@ -591,7 +595,14 @@ class DAQ_Move(ParameterControlModule):
|
|
|
591
595
|
def units(self, unit: str):
|
|
592
596
|
self.settings.child('move_settings', 'units').setValue(unit)
|
|
593
597
|
if self.ui is not None and config('actuator', 'display_units'):
|
|
594
|
-
|
|
598
|
+
if unit == '°':
|
|
599
|
+
# special cas as pint base unit for angles are radians
|
|
600
|
+
self.ui.set_unit_as_suffix(unit)
|
|
601
|
+
else:
|
|
602
|
+
# if the controller units are in mm the displayed unit will be m
|
|
603
|
+
# because m is the base unit
|
|
604
|
+
# then the user could ask for mm, km, µm...
|
|
605
|
+
self.ui.set_unit_as_suffix(str(Q_(1, unit).to_base_units().units))
|
|
595
606
|
|
|
596
607
|
def update_settings(self):
|
|
597
608
|
|
|
@@ -668,8 +679,6 @@ class DAQ_Move_Hardware(QObject):
|
|
|
668
679
|
self._title = title
|
|
669
680
|
self.hardware: Optional[DAQ_Move_base] = None
|
|
670
681
|
self.actuator_type = actuator_type
|
|
671
|
-
self.current_position: DataActuator = position
|
|
672
|
-
self._target_value: Optional[DataActuator] = None
|
|
673
682
|
self.hardware_adress = None
|
|
674
683
|
self.axis_address = None
|
|
675
684
|
self.motion_stoped = False
|
|
@@ -692,9 +701,8 @@ class DAQ_Move_Hardware(QObject):
|
|
|
692
701
|
"""
|
|
693
702
|
pos = self.hardware.get_actuator_value()
|
|
694
703
|
if self.hardware.data_actuator_type == DataActuatorType.float:
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
return pos
|
|
704
|
+
pos = DataActuator(self._title, data=pos, units=self.hardware.axis_unit)
|
|
705
|
+
return pos
|
|
698
706
|
|
|
699
707
|
def check_position(self):
|
|
700
708
|
"""Get the current position checking the hardware position (deprecated)
|
|
@@ -743,6 +751,8 @@ class DAQ_Move_Hardware(QObject):
|
|
|
743
751
|
status.initialized = infos[1]
|
|
744
752
|
status.controller = self.hardware.controller
|
|
745
753
|
self.hardware.move_done_signal.connect(self.move_done)
|
|
754
|
+
if status.initialized:
|
|
755
|
+
self.status_sig.emit(ThreadCommand('get_actuator_value', [self.get_actuator_value()]))
|
|
746
756
|
|
|
747
757
|
return status
|
|
748
758
|
except Exception as e:
|
|
@@ -753,15 +763,13 @@ class DAQ_Move_Hardware(QObject):
|
|
|
753
763
|
"""
|
|
754
764
|
|
|
755
765
|
"""
|
|
756
|
-
|
|
757
|
-
# position = float(position) # because it may be a numpy float and could cause issues
|
|
758
|
-
# # see https://github.com/pythonnet/pythonnet/issues/1833
|
|
759
|
-
self._target_value = position
|
|
766
|
+
position = check_units(position, self.hardware.axis_unit)
|
|
760
767
|
self.hardware.move_is_done = False
|
|
761
768
|
self.hardware.ispolling = polling
|
|
762
769
|
if self.hardware.data_actuator_type.name == 'float':
|
|
763
770
|
self.hardware.move_abs(position.value())
|
|
764
771
|
else:
|
|
772
|
+
position.units = self.hardware.axis_unit # convert to plugin controller current axis units
|
|
765
773
|
self.hardware.move_abs(position)
|
|
766
774
|
self.hardware.poll_moving()
|
|
767
775
|
|
|
@@ -769,14 +777,14 @@ class DAQ_Move_Hardware(QObject):
|
|
|
769
777
|
"""
|
|
770
778
|
|
|
771
779
|
"""
|
|
772
|
-
|
|
780
|
+
rel_position = check_units(rel_position, self.hardware.axis_unit)
|
|
773
781
|
self.hardware.move_is_done = False
|
|
774
|
-
self._target_value = self.current_position + rel_position
|
|
775
782
|
self.hardware.ispolling = polling
|
|
776
783
|
|
|
777
784
|
if self.hardware.data_actuator_type.name == 'float':
|
|
778
785
|
self.hardware.move_rel(rel_position.value())
|
|
779
786
|
else:
|
|
787
|
+
rel_position.units = self.hardware.axis_unit # convert to plugin current axis units
|
|
780
788
|
self.hardware.move_rel(rel_position)
|
|
781
789
|
|
|
782
790
|
self.hardware.poll_moving()
|
|
@@ -798,7 +806,6 @@ class DAQ_Move_Hardware(QObject):
|
|
|
798
806
|
|
|
799
807
|
"""
|
|
800
808
|
self.hardware.move_is_done = False
|
|
801
|
-
self._target_value = 0
|
|
802
809
|
self.hardware.move_home()
|
|
803
810
|
|
|
804
811
|
@Slot(DataActuator)
|
|
@@ -7,6 +7,7 @@ Created the 28/07/2022
|
|
|
7
7
|
|
|
8
8
|
from typing import List
|
|
9
9
|
import sys
|
|
10
|
+
from pint.errors import DimensionalityError
|
|
10
11
|
|
|
11
12
|
from qtpy import QtWidgets
|
|
12
13
|
from qtpy.QtCore import Signal, Qt
|
|
@@ -65,12 +66,17 @@ class DAQ_Move_UI(ControlModuleUI):
|
|
|
65
66
|
|
|
66
67
|
super().__init__(parent)
|
|
67
68
|
self.title = title
|
|
69
|
+
self._unit = ''
|
|
68
70
|
self.setup_ui()
|
|
69
71
|
|
|
70
72
|
self.enable_move_buttons(False)
|
|
71
73
|
|
|
72
74
|
def display_value(self, value: DataActuator):
|
|
73
|
-
|
|
75
|
+
try:
|
|
76
|
+
self.current_value_sb.setValue(value.value(self._unit))
|
|
77
|
+
except DimensionalityError as e:
|
|
78
|
+
value.force_units(self._unit)
|
|
79
|
+
self.current_value_sb.setValue(value.value())
|
|
74
80
|
|
|
75
81
|
@property
|
|
76
82
|
def actuator_init(self):
|
|
@@ -193,9 +199,9 @@ class DAQ_Move_UI(ControlModuleUI):
|
|
|
193
199
|
self.main_ui.layout().addWidget(self.toolbar, 0, 0, 1, 2)
|
|
194
200
|
self.main_ui.layout().addWidget(self.move_toolbar, 1, 0, 1, 2)
|
|
195
201
|
|
|
196
|
-
self.abs_value_sb = SpinBox(step=0.1, dec=True)
|
|
202
|
+
self.abs_value_sb = SpinBox(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'))
|
|
197
203
|
self.abs_value_sb.setStyleSheet("background-color : lightgreen; color: black")
|
|
198
|
-
self.abs_value_sb_2 = SpinBox(step=0.1, dec=True)
|
|
204
|
+
self.abs_value_sb_2 = SpinBox(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'))
|
|
199
205
|
self.abs_value_sb_2.setStyleSheet("background-color : lightcoral; color: black")
|
|
200
206
|
self.move_toolbar.addWidget(self.abs_value_sb)
|
|
201
207
|
self.move_toolbar.addWidget(self.abs_value_sb_2)
|
|
@@ -221,7 +227,7 @@ class DAQ_Move_UI(ControlModuleUI):
|
|
|
221
227
|
self.control_ui.layout().addWidget(LabelWithFont('Abs. Value'), 0, 0)
|
|
222
228
|
self.find_home_pb = PushButtonIcon('home2', 'Find Home')
|
|
223
229
|
self.control_ui.layout().addWidget(self.find_home_pb, 0, 1)
|
|
224
|
-
self.abs_value_sb_bis = SpinBox(step=0.1, dec=True)
|
|
230
|
+
self.abs_value_sb_bis = SpinBox(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'))
|
|
225
231
|
self.control_ui.layout().addWidget(self.abs_value_sb_bis, 1, 0)
|
|
226
232
|
self.move_abs_pb = PushButtonIcon('Move', 'Set Abs.',
|
|
227
233
|
tip='Set the value of the actuator to the set absolute value')
|
|
@@ -230,7 +236,7 @@ class DAQ_Move_UI(ControlModuleUI):
|
|
|
230
236
|
self.move_rel_plus_pb = PushButtonIcon('MoveUp', 'Set Rel. (+)')
|
|
231
237
|
self.control_ui.layout().addWidget(self.move_rel_plus_pb, 2, 1)
|
|
232
238
|
|
|
233
|
-
self.rel_value_sb = SpinBox(step=0.1, dec=True)
|
|
239
|
+
self.rel_value_sb = SpinBox(step=0.1, dec=True, siPrefix=config('actuator', 'siprefix'))
|
|
234
240
|
self.control_ui.layout().addWidget(self.rel_value_sb, 3, 0)
|
|
235
241
|
self.move_rel_minus_pb = PushButtonIcon('MoveDown', 'Set Rel. (-)')
|
|
236
242
|
self.control_ui.layout().addWidget(self.move_rel_minus_pb, 3, 1)
|
|
@@ -252,6 +258,7 @@ class DAQ_Move_UI(ControlModuleUI):
|
|
|
252
258
|
|
|
253
259
|
def set_unit_as_suffix(self, unit: str):
|
|
254
260
|
"""Will append the actuator units in the value display"""
|
|
261
|
+
self._unit = unit
|
|
255
262
|
self.current_value_sb.setOpts(suffix=unit)
|
|
256
263
|
self.abs_value_sb_bis.setOpts(suffix=unit)
|
|
257
264
|
self.abs_value_sb.setOpts(suffix=unit)
|
|
@@ -328,12 +335,14 @@ class DAQ_Move_UI(ControlModuleUI):
|
|
|
328
335
|
|
|
329
336
|
def emit_move_abs(self, spinbox):
|
|
330
337
|
spinbox.editingFinished.emit()
|
|
331
|
-
self.command_sig.emit(ThreadCommand('move_abs', DataActuator(data=spinbox.value()
|
|
338
|
+
self.command_sig.emit(ThreadCommand('move_abs', DataActuator(data=spinbox.value(),
|
|
339
|
+
units=self._unit)))
|
|
332
340
|
|
|
333
341
|
def emit_move_rel(self, sign):
|
|
334
|
-
self.command_sig.emit(ThreadCommand(
|
|
335
|
-
|
|
336
|
-
|
|
342
|
+
self.command_sig.emit(ThreadCommand(
|
|
343
|
+
'move_rel',
|
|
344
|
+
DataActuator(data=self.rel_value_sb.value() * (1 if sign == '+' else -1),
|
|
345
|
+
units=self._unit)))
|
|
337
346
|
|
|
338
347
|
def close(self):
|
|
339
348
|
self.graph_ui.close()
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import numbers
|
|
2
|
+
|
|
1
3
|
from time import perf_counter
|
|
2
4
|
from typing import Union, List, Dict, TYPE_CHECKING, Optional
|
|
3
5
|
from numbers import Number
|
|
6
|
+
from collections.abc import Iterable
|
|
4
7
|
|
|
5
8
|
from easydict import EasyDict as edict
|
|
6
9
|
import numpy as np
|
|
@@ -30,13 +33,45 @@ logger = set_logger(get_module_name(__file__))
|
|
|
30
33
|
config = configmod.Config()
|
|
31
34
|
|
|
32
35
|
|
|
36
|
+
def check_units(dwa: DataActuator, units: str):
|
|
37
|
+
""" Check if dwa units is compatible with the units argument
|
|
38
|
+
|
|
39
|
+
If it is incompatible and has dimensionless units, brute force change the dwa units to units,
|
|
40
|
+
otherwise raise a DataUnitError
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
dwa: DataActuator
|
|
45
|
+
units: str
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
DataActuator
|
|
50
|
+
"""
|
|
51
|
+
if Unit(dwa.units).is_compatible_with(units):
|
|
52
|
+
return dwa
|
|
53
|
+
elif Unit(dwa.units).dimensionless: # dimensionless
|
|
54
|
+
dwa.force_units(units)
|
|
55
|
+
return dwa
|
|
56
|
+
else:
|
|
57
|
+
raise DataUnitError(f'Units incompatibility between {dwa} and "{units}" units')
|
|
58
|
+
|
|
59
|
+
|
|
33
60
|
class DataActuatorType(BaseEnum):
|
|
34
61
|
"""Enum for new or old style holding the value of the actuator"""
|
|
35
62
|
float = 0
|
|
36
63
|
DataActuator = 1
|
|
37
64
|
|
|
38
65
|
|
|
39
|
-
def comon_parameters(epsilon=config('actuator', 'epsilon_default')
|
|
66
|
+
def comon_parameters(epsilon=config('actuator', 'epsilon_default'),
|
|
67
|
+
epsilons=None):
|
|
68
|
+
if epsilons is not None:
|
|
69
|
+
epsilon=epsilons
|
|
70
|
+
if isinstance(epsilon, list):
|
|
71
|
+
epsilon=epsilon[0]
|
|
72
|
+
elif isinstance(epsilon, dict):
|
|
73
|
+
epsilon=epsilon[list[epsilon.keys()][0]]
|
|
74
|
+
|
|
40
75
|
return [{'title': 'Units:', 'name': 'units', 'type': 'str', 'value': '', 'readonly': True},
|
|
41
76
|
{'title': 'Epsilon:', 'name': 'epsilon', 'type': 'float',
|
|
42
77
|
'value': epsilon,
|
|
@@ -79,32 +114,45 @@ class MoveCommand:
|
|
|
79
114
|
self.value = value
|
|
80
115
|
|
|
81
116
|
|
|
82
|
-
def comon_parameters_fun(is_multiaxes
|
|
83
|
-
axes_names = [],
|
|
117
|
+
def comon_parameters_fun(is_multiaxes=False, axes_names=None,
|
|
84
118
|
axis_names: Union[List, Dict] = [],
|
|
85
|
-
master
|
|
86
|
-
epsilon = config('actuator', 'epsilon_default')):
|
|
119
|
+
master=True,
|
|
120
|
+
epsilon: float = config('actuator', 'epsilon_default')):
|
|
121
|
+
|
|
87
122
|
"""Function returning the common and mandatory parameters that should be on the actuator plugin level
|
|
88
123
|
|
|
89
124
|
Parameters
|
|
90
125
|
----------
|
|
91
|
-
is_multiaxes: bool
|
|
126
|
+
is_multiaxes: bool # deprecated not need anymore
|
|
92
127
|
If True, display the particular settings to define which axis the controller is driving
|
|
93
|
-
|
|
128
|
+
axes_names: deprecated, use axis_names
|
|
129
|
+
axis_names: list of str or dictionnary of string as key and integer as value
|
|
94
130
|
The string identifier of every axis the controller can drive
|
|
95
131
|
master: bool
|
|
96
132
|
If True consider this plugin has to init the controller, otherwise use an already initialized instance
|
|
133
|
+
epsilon: float
|
|
134
|
+
deprecated (< 5.0.0) no more used here
|
|
135
|
+
|
|
97
136
|
"""
|
|
98
|
-
if
|
|
137
|
+
if axes_names is not None and len(axis_names) == 0:
|
|
138
|
+
if len(axes_names) == 0:
|
|
139
|
+
axes_names = ['']
|
|
99
140
|
axis_names = axes_names
|
|
100
141
|
|
|
142
|
+
is_multiaxes = len(axis_names) > 1
|
|
143
|
+
if isinstance(axis_names, list):
|
|
144
|
+
axis_name = axis_names[0]
|
|
145
|
+
elif isinstance(axis_names, dict):
|
|
146
|
+
axis_name = axis_names[list(axis_names.keys())[0]]
|
|
101
147
|
params = [
|
|
102
|
-
{'title': 'MultiAxes:', 'name': 'multiaxes', 'type': 'group',
|
|
103
|
-
|
|
104
|
-
|
|
148
|
+
{'title': 'MultiAxes:', 'name': 'multiaxes', 'type': 'group',
|
|
149
|
+
'visible': is_multiaxes, 'children': [
|
|
150
|
+
{'title': 'is Multiaxes:', 'name': 'ismultiaxes', 'type': 'bool',
|
|
151
|
+
'value': is_multiaxes, 'default': False},
|
|
105
152
|
{'title': 'Status:', 'name': 'multi_status', 'type': 'list',
|
|
106
153
|
'value': 'Master' if master else 'Slave', 'limits': ['Master', 'Slave']},
|
|
107
|
-
{'title': 'Axis:', 'name': 'axis', 'type': 'list', 'limits': axis_names
|
|
154
|
+
{'title': 'Axis:', 'name': 'axis', 'type': 'list', 'limits': axis_names,
|
|
155
|
+
'value': axis_name},
|
|
108
156
|
]},
|
|
109
157
|
] + comon_parameters(epsilon)
|
|
110
158
|
return params
|
|
@@ -204,10 +252,16 @@ class DAQ_Move_base(QObject):
|
|
|
204
252
|
|
|
205
253
|
move_done_signal = Signal(DataActuator)
|
|
206
254
|
is_multiaxes = False
|
|
207
|
-
stage_names = []
|
|
255
|
+
stage_names = [] # deprecated
|
|
256
|
+
|
|
257
|
+
_axis_names: Union[list, Dict[str, int]] = None
|
|
258
|
+
_controller_units: Union[str, List[str], Dict[str, int]] = ''
|
|
259
|
+
_epsilons: Union[float, List[float], Dict[str, float]] = None
|
|
260
|
+
_epsilon = 1.0 # deprecated
|
|
261
|
+
|
|
262
|
+
|
|
208
263
|
params = []
|
|
209
|
-
|
|
210
|
-
_epsilon = 1
|
|
264
|
+
|
|
211
265
|
data_actuator_type = DataActuatorType.float
|
|
212
266
|
data_shape = (1, ) # expected shape of the underlying actuator's value (in general a float so shape = (1, ))
|
|
213
267
|
|
|
@@ -237,18 +291,19 @@ class DAQ_Move_base(QObject):
|
|
|
237
291
|
else:
|
|
238
292
|
self._title = "myactuator"
|
|
239
293
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
self.
|
|
294
|
+
self._axis_units: Union[Dict[str, str], List[str]] = None
|
|
295
|
+
self.axis_units = self._controller_units
|
|
296
|
+
if self._epsilons is None:
|
|
297
|
+
self._epsilons = self._epsilon
|
|
298
|
+
self.epsilons = self._epsilons
|
|
299
|
+
self.axis_name = self.axis_name # to trigger some actions on units and epsilons
|
|
244
300
|
|
|
245
301
|
self._current_value = DataActuator(self._title,
|
|
246
302
|
data=[np.zeros(self.data_shape, dtype=float)],
|
|
247
|
-
units=self.
|
|
303
|
+
units=self.axis_unit)
|
|
248
304
|
self._target_value = DataActuator(self._title,
|
|
249
305
|
data=[np.zeros(self.data_shape, dtype=float)],
|
|
250
|
-
units=self.
|
|
251
|
-
self.controller_units = self._controller_units
|
|
306
|
+
units=self.axis_unit)
|
|
252
307
|
|
|
253
308
|
self.poll_timer = QTimer()
|
|
254
309
|
self.poll_timer.setInterval(config('actuator', 'polling_interval_ms'))
|
|
@@ -258,7 +313,108 @@ class DAQ_Move_base(QObject):
|
|
|
258
313
|
self.ini_attributes()
|
|
259
314
|
|
|
260
315
|
@property
|
|
261
|
-
def
|
|
316
|
+
def axis_unit(self) -> str:
|
|
317
|
+
""" Get/set the unit of the currently chosen axis
|
|
318
|
+
|
|
319
|
+
Will update the printed controller unit in the UI
|
|
320
|
+
|
|
321
|
+
New in 4.4.0
|
|
322
|
+
"""
|
|
323
|
+
return self.axis_units[self.axis_index_key]
|
|
324
|
+
|
|
325
|
+
@axis_unit.setter
|
|
326
|
+
def axis_unit(self, unit: str):
|
|
327
|
+
self.axis_units[self.axis_index_key] = unit
|
|
328
|
+
self.settings.child('units').setValue(unit)
|
|
329
|
+
self.emit_status(ThreadCommand('units', unit))
|
|
330
|
+
|
|
331
|
+
@property
|
|
332
|
+
def axis_units(self) -> Union[List[str], Dict[str, str]]:
|
|
333
|
+
""" Get/Set the units for each axis of the controller
|
|
334
|
+
|
|
335
|
+
New in 4.4.0
|
|
336
|
+
"""
|
|
337
|
+
return self._axis_units
|
|
338
|
+
|
|
339
|
+
@axis_units.setter
|
|
340
|
+
def axis_units(self, units: Union[str, List[str], Dict[str, str]]):
|
|
341
|
+
if isinstance(units, str):
|
|
342
|
+
if isinstance(self.axis_names, list):
|
|
343
|
+
units_tmp = [units for _ in range(len(self.axis_names))]
|
|
344
|
+
else:
|
|
345
|
+
units_tmp = {}
|
|
346
|
+
for key in self.axis_names:
|
|
347
|
+
units_tmp[key] = units
|
|
348
|
+
else:
|
|
349
|
+
if not isinstance(units, type(self.axis_names)):
|
|
350
|
+
raise TypeError('units should be defined just like axis_names: a str, list of string or'
|
|
351
|
+
'dict of string')
|
|
352
|
+
if len(units) != len(self.axis_names):
|
|
353
|
+
raise ValueError('Units should be defined either as a single str or a list/dict with'
|
|
354
|
+
'a str defined for each axis')
|
|
355
|
+
units_tmp = units
|
|
356
|
+
self._axis_units = units_tmp
|
|
357
|
+
|
|
358
|
+
@property
|
|
359
|
+
def epsilon(self) -> float:
|
|
360
|
+
""" Get/Set the epsilon of the currently chosen axis
|
|
361
|
+
|
|
362
|
+
New in 4.4.0
|
|
363
|
+
"""
|
|
364
|
+
return self.epsilons[self.axis_index_key]
|
|
365
|
+
|
|
366
|
+
@epsilon.setter
|
|
367
|
+
def epsilon(self, eps: float):
|
|
368
|
+
self.epsilons[self.axis_index_key] = eps
|
|
369
|
+
|
|
370
|
+
@property
|
|
371
|
+
def epsilons(self) -> Union[List[float], Dict[str, float]]:
|
|
372
|
+
""" Get/Set the epsilon for each axis of the controller
|
|
373
|
+
|
|
374
|
+
New in 4.4.0
|
|
375
|
+
"""
|
|
376
|
+
return self._epsilons
|
|
377
|
+
|
|
378
|
+
@epsilons.setter
|
|
379
|
+
def epsilons(self, epsilons: Union[float, List[float], Dict[str, float]]):
|
|
380
|
+
if isinstance(epsilons, numbers.Number):
|
|
381
|
+
if isinstance(self.axis_names, list):
|
|
382
|
+
epsilons_tmp = [epsilons for _ in range(len(self.axis_names))]
|
|
383
|
+
else:
|
|
384
|
+
epsilons_tmp = {}
|
|
385
|
+
for key in self.axis_names:
|
|
386
|
+
epsilons_tmp[key] = epsilons
|
|
387
|
+
else:
|
|
388
|
+
if not isinstance(epsilons, type(self.axis_names)):
|
|
389
|
+
raise TypeError('units should be defined just like axis_names: a float, list of '
|
|
390
|
+
'float or dict of float')
|
|
391
|
+
if len(epsilons) != len(self.axis_names):
|
|
392
|
+
raise ValueError('epsilons should be defined either as a single float or a '
|
|
393
|
+
'list/dict with'
|
|
394
|
+
'a float defined for each axis')
|
|
395
|
+
epsilons_tmp = epsilons
|
|
396
|
+
self._epsilons = epsilons_tmp
|
|
397
|
+
|
|
398
|
+
@property
|
|
399
|
+
def controller_units(self):
|
|
400
|
+
""" Get/Set the units of the currently chosen axis of the controller
|
|
401
|
+
|
|
402
|
+
Deprecated with pymodaq >= 4.4.0
|
|
403
|
+
|
|
404
|
+
The property controller_units is deprecated please use the axis_unit property
|
|
405
|
+
"""
|
|
406
|
+
deprecation_msg('The property controller_units is deprecated please use the'
|
|
407
|
+
'axis_unit property.')
|
|
408
|
+
return self.axis_unit
|
|
409
|
+
|
|
410
|
+
@controller_units.setter
|
|
411
|
+
def controller_units(self, units: str = ''):
|
|
412
|
+
deprecation_msg('The property controller_units is deprecated please use the'
|
|
413
|
+
'axis_unit property.')
|
|
414
|
+
self._axis_units[self.axis_index_key] = units
|
|
415
|
+
|
|
416
|
+
@property
|
|
417
|
+
def axis_name(self) -> Union[str]:
|
|
262
418
|
"""Get/Set the current axis using its string identifier"""
|
|
263
419
|
limits = self.settings.child('multiaxes', 'axis').opts['limits']
|
|
264
420
|
if isinstance(limits, list):
|
|
@@ -275,6 +431,9 @@ class DAQ_Move_base(QObject):
|
|
|
275
431
|
elif isinstance(limits, dict):
|
|
276
432
|
self.settings.child('multiaxes', 'axis').setValue(limits[name])
|
|
277
433
|
QtWidgets.QApplication.processEvents()
|
|
434
|
+
self.axis_unit = self.axis_unit
|
|
435
|
+
self.settings.child('epsilon').setValue(self.epsilon)
|
|
436
|
+
|
|
278
437
|
|
|
279
438
|
@property
|
|
280
439
|
def axis_names(self) -> Union[List, Dict]:
|
|
@@ -292,9 +451,29 @@ class DAQ_Move_base(QObject):
|
|
|
292
451
|
QtWidgets.QApplication.processEvents()
|
|
293
452
|
|
|
294
453
|
@property
|
|
295
|
-
def axis_value(self) ->
|
|
296
|
-
"""Get the current value selected from the current axis
|
|
297
|
-
|
|
454
|
+
def axis_value(self) -> int:
|
|
455
|
+
"""Get the current value selected from the current axis
|
|
456
|
+
|
|
457
|
+
In case axis_names is a list, return the element of the list: self.axis_name
|
|
458
|
+
In case axis_names is a dict, return the value of the dict self.axis_names[self.axis_name]
|
|
459
|
+
"""
|
|
460
|
+
if isinstance(self.axis_names, list):
|
|
461
|
+
return self.axis_name
|
|
462
|
+
else:
|
|
463
|
+
return self.axis_names[self.axis_name]
|
|
464
|
+
|
|
465
|
+
@property
|
|
466
|
+
def axis_index_key(self) -> Union[int, str]:
|
|
467
|
+
""" Get the current index or key correspondingto the current axis
|
|
468
|
+
|
|
469
|
+
In case axis_names is a list, return the index wihtin the list
|
|
470
|
+
In case axis_names is a dict, return the key of the dict self.axis_name
|
|
471
|
+
|
|
472
|
+
"""
|
|
473
|
+
if isinstance(self.axis_names, list):
|
|
474
|
+
return self.axis_names.index(self.axis_name)
|
|
475
|
+
else:
|
|
476
|
+
return self.axis_name
|
|
298
477
|
|
|
299
478
|
def ini_attributes(self):
|
|
300
479
|
""" To be subclassed, in order to init specific attributes needed by the real implementation"""
|
|
@@ -334,40 +513,40 @@ class DAQ_Move_base(QObject):
|
|
|
334
513
|
|
|
335
514
|
@property
|
|
336
515
|
def current_value(self):
|
|
337
|
-
if self.data_actuator_type
|
|
516
|
+
if self.data_actuator_type == self.data_actuator_type.float:
|
|
338
517
|
return self._current_value.value()
|
|
339
518
|
else:
|
|
340
519
|
return self._current_value
|
|
341
520
|
|
|
342
521
|
@current_value.setter
|
|
343
522
|
def current_value(self, value: Union[float, DataActuator]):
|
|
344
|
-
if
|
|
523
|
+
if isinstance(value, numbers.Number):
|
|
345
524
|
self._current_value = DataActuator(self._title, data=value,
|
|
346
|
-
units=self.
|
|
525
|
+
units=self.axis_unit)
|
|
347
526
|
else:
|
|
348
|
-
if (not Unit(self.
|
|
527
|
+
if (not Unit(self.axis_unit).is_compatible_with(
|
|
349
528
|
Unit(value.units)) and
|
|
350
529
|
value.units == ''):
|
|
351
|
-
value.force_units(self.
|
|
530
|
+
value.force_units(self.axis_unit)
|
|
352
531
|
self._current_value = value
|
|
353
532
|
|
|
354
533
|
@property
|
|
355
534
|
def target_value(self):
|
|
356
|
-
if self.data_actuator_type.name ==
|
|
535
|
+
if self.data_actuator_type.name == self.data_actuator_type.float:
|
|
357
536
|
return self._target_value.value()
|
|
358
537
|
else:
|
|
359
538
|
return self._target_value
|
|
360
539
|
|
|
361
540
|
@target_value.setter
|
|
362
|
-
def target_value(self, value: Union[
|
|
363
|
-
if
|
|
541
|
+
def target_value(self, value: Union[numbers.Number, DataActuator]):
|
|
542
|
+
if isinstance(value, numbers.Number):
|
|
364
543
|
self._target_value = DataActuator(self._title, data=value,
|
|
365
|
-
units=self.
|
|
544
|
+
units=self.axis_unit)
|
|
366
545
|
else:
|
|
367
|
-
if (not Unit(self.
|
|
546
|
+
if (not Unit(self.axis_unit).is_compatible_with(
|
|
368
547
|
Unit(value.units)) and
|
|
369
548
|
value.units == ''):
|
|
370
|
-
value.force_units(self.
|
|
549
|
+
value.force_units(self.axis_unit)
|
|
371
550
|
self._target_value = value
|
|
372
551
|
|
|
373
552
|
@property
|
|
@@ -396,19 +575,6 @@ class DAQ_Move_base(QObject):
|
|
|
396
575
|
"""
|
|
397
576
|
return self.settings['multiaxes', 'multi_status'] == 'Master'
|
|
398
577
|
|
|
399
|
-
@property
|
|
400
|
-
def controller_units(self):
|
|
401
|
-
""" Get/Set the units of this plugin"""
|
|
402
|
-
return self._controller_units
|
|
403
|
-
|
|
404
|
-
@controller_units.setter
|
|
405
|
-
def controller_units(self, units: str = ''):
|
|
406
|
-
self._controller_units = units
|
|
407
|
-
try:
|
|
408
|
-
self.settings.child('units').setValue(units)
|
|
409
|
-
self.emit_status(ThreadCommand('units', units))
|
|
410
|
-
except Exception:
|
|
411
|
-
pass
|
|
412
578
|
|
|
413
579
|
@property
|
|
414
580
|
def ispolling(self):
|
|
@@ -428,12 +594,12 @@ class DAQ_Move_base(QObject):
|
|
|
428
594
|
if position > self.settings.child('bounds', 'max_bound').value():
|
|
429
595
|
position = DataActuator(self._title,
|
|
430
596
|
data=self.settings.child('bounds', 'max_bound').value(),
|
|
431
|
-
units
|
|
597
|
+
units=self.axis_unit)
|
|
432
598
|
self.emit_status(ThreadCommand('outofbounds', []))
|
|
433
599
|
elif position < self.settings.child('bounds', 'min_bound').value():
|
|
434
600
|
position = DataActuator(self._title,
|
|
435
601
|
data=self.settings.child('bounds', 'min_bound').value(),
|
|
436
|
-
units=self.
|
|
602
|
+
units=self.axis_unit
|
|
437
603
|
)
|
|
438
604
|
self.emit_status(ThreadCommand('outofbounds', []))
|
|
439
605
|
return position
|
|
@@ -502,13 +668,13 @@ class DAQ_Move_base(QObject):
|
|
|
502
668
|
if position is None:
|
|
503
669
|
if self.data_actuator_type.name == 'float':
|
|
504
670
|
position = DataActuator(self._title, data=self.get_actuator_value(),
|
|
505
|
-
units
|
|
671
|
+
units=self.axis_unit)
|
|
506
672
|
else:
|
|
507
673
|
position = self.get_actuator_value()
|
|
508
674
|
if position.name != self._title: # make sure the emitted DataActuator has the name of the real implementation
|
|
509
675
|
#of the plugin
|
|
510
676
|
position = DataActuator(self._title, data=position.value(),
|
|
511
|
-
units
|
|
677
|
+
units=self.axis_unit)
|
|
512
678
|
self.move_done_signal.emit(position)
|
|
513
679
|
self.move_is_done = True
|
|
514
680
|
|
|
@@ -526,32 +692,59 @@ class DAQ_Move_base(QObject):
|
|
|
526
692
|
else:
|
|
527
693
|
if self.data_actuator_type == DataActuatorType.float:
|
|
528
694
|
self._current_value = DataActuator(data=self.get_actuator_value(),
|
|
529
|
-
units=self.
|
|
695
|
+
units=self.axis_unit)
|
|
530
696
|
else:
|
|
531
697
|
self._current_value = self.get_actuator_value()
|
|
532
|
-
if (not Unit(self.
|
|
698
|
+
if (not Unit(self.axis_unit).is_compatible_with(
|
|
533
699
|
Unit(self._current_value.units)) and
|
|
534
700
|
self._current_value.units == ''):
|
|
535
701
|
# this happens if the units have not been specified in
|
|
536
702
|
# the plugin
|
|
537
|
-
self._current_value.force_units(self.
|
|
703
|
+
self._current_value.force_units(self.axis_unit)
|
|
538
704
|
|
|
539
705
|
logger.debug(f'Current position: {self._current_value}')
|
|
540
706
|
self.move_done(self._current_value)
|
|
541
707
|
|
|
542
|
-
def
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
708
|
+
def _condition_to_reach_target(self) -> bool:
|
|
709
|
+
""" Implement the condition for exiting the polling mechanism and specifying that the
|
|
710
|
+
target value has been reached
|
|
711
|
+
|
|
712
|
+
Returns
|
|
713
|
+
-------
|
|
714
|
+
bool: if True, PyMoDAQ considers the target value has been reached at epsilon
|
|
546
715
|
|
|
716
|
+
See Also
|
|
717
|
+
--------
|
|
718
|
+
user_condition_to_reach_target
|
|
719
|
+
"""
|
|
547
720
|
try:
|
|
548
|
-
epsilon_calculated = (
|
|
721
|
+
epsilon_calculated = (
|
|
722
|
+
self._current_value - self._target_value).abs().value(self.axis_unit)
|
|
549
723
|
except DataUnitError as e:
|
|
550
724
|
epsilon_calculated = abs(self._current_value.value() - self._target_value.value())
|
|
551
|
-
logger.warning(f'Unit issue when calculating epsilon, units are not
|
|
725
|
+
logger.warning(f'Unit issue when calculating epsilon, units are not compatible between'
|
|
552
726
|
f'target and current values')
|
|
553
727
|
|
|
554
|
-
|
|
728
|
+
return (epsilon_calculated < self.epsilon) and self.user_condition_to_reach_target()
|
|
729
|
+
|
|
730
|
+
def user_condition_to_reach_target(self) -> bool:
|
|
731
|
+
""" Implement a user defined condition for exiting the polling mechanism and specifying
|
|
732
|
+
that the target value has been reached (on top of the existing epsilon mechanism)
|
|
733
|
+
|
|
734
|
+
Should be reimplemented in plugins to implement other conditions
|
|
735
|
+
|
|
736
|
+
Returns
|
|
737
|
+
-------
|
|
738
|
+
bool: if True, PyMoDAQ considers the target value has been reached
|
|
739
|
+
"""
|
|
740
|
+
return True
|
|
741
|
+
|
|
742
|
+
def check_target_reached(self):
|
|
743
|
+
logger.debug(f"epsilon value is {self.epsilon}")
|
|
744
|
+
logger.debug(f"current_value value is {self._current_value}")
|
|
745
|
+
logger.debug(f"target_value value is {self._target_value}")
|
|
746
|
+
|
|
747
|
+
if not self._condition_to_reach_target():
|
|
555
748
|
|
|
556
749
|
logger.debug(f'Check move_is_done: {self.move_is_done}')
|
|
557
750
|
if self.move_is_done:
|
|
@@ -647,6 +840,11 @@ class DAQ_Move_base(QObject):
|
|
|
647
840
|
self.commit_common_settings(param)
|
|
648
841
|
self.commit_settings(param)
|
|
649
842
|
|
|
843
|
+
if param.name() == 'axis':
|
|
844
|
+
self.axis_name = param.value()
|
|
845
|
+
elif param.name() == 'epsilon':
|
|
846
|
+
self.epsilon = param.value()
|
|
847
|
+
|
|
650
848
|
|
|
651
849
|
class DAQ_Move_TCP_server(DAQ_Move_base, TCPServer):
|
|
652
850
|
"""
|
pymodaq/examples/parameter_ex.py
CHANGED
|
@@ -22,6 +22,8 @@ class ParameterEx(ParameterManager):
|
|
|
22
22
|
{'title': 'Numbers:', 'name': 'numbers', 'type': 'group', 'children': [
|
|
23
23
|
{'title': 'Standard float', 'name': 'afloat', 'type': 'float', 'value': 20., 'min': 1.,
|
|
24
24
|
'tip': 'displays this text as a tooltip'},
|
|
25
|
+
{'title': 'Standard float with Si prefix', 'name': 'afloatprefix', 'type': 'float', 'value': 20.,
|
|
26
|
+
'tip': 'displays this text as a tooltip', 'siPrefix': True, 'suffix': 'V'},
|
|
25
27
|
{'title': 'Linear Slide float', 'name': 'linearslidefloat', 'type': 'slide', 'value': 50, 'default': 50,
|
|
26
28
|
'min': 0,
|
|
27
29
|
'max': 123, 'subtype': 'linear'},
|
pymodaq/resources/VERSION
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
version = '4.
|
|
1
|
+
version = '4.4.2'
|
|
2
2
|
|
pymodaq/utils/config.py
CHANGED
|
@@ -20,7 +20,7 @@ except:
|
|
|
20
20
|
USER = 'unknown_user'
|
|
21
21
|
|
|
22
22
|
CONFIG_BASE_PATH = Path(environ['PROGRAMDATA']) if sys.platform == 'win32' else \
|
|
23
|
-
Path('
|
|
23
|
+
Path('Library/Application Support') if sys.platform == 'darwin' else Path('/etc')
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
KeyType = TypeVar('KeyType')
|
pymodaq/utils/data.py
CHANGED
|
@@ -2413,21 +2413,48 @@ class DataActuator(DataRaw):
|
|
|
2413
2413
|
else:
|
|
2414
2414
|
return f'<{self.__class__.__name__} ({self.shape} {self.units})>'
|
|
2415
2415
|
|
|
2416
|
-
def value(self) -> float:
|
|
2416
|
+
def value(self, units: str = None) -> float:
|
|
2417
2417
|
"""Returns the underlying float value (of the first elt in the data list) if this data
|
|
2418
|
-
holds only a float otherwise returns a mean of the underlying data
|
|
2418
|
+
holds only a float otherwise returns a mean of the underlying data
|
|
2419
|
+
|
|
2420
|
+
Parameters
|
|
2421
|
+
----------
|
|
2422
|
+
|
|
2423
|
+
units: str
|
|
2424
|
+
if unit is compatible with self.units, convert the data to these new units before
|
|
2425
|
+
getting the value
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
"""
|
|
2419
2429
|
if self.length == 1 and self.size == 1:
|
|
2420
|
-
|
|
2430
|
+
if units is not None:
|
|
2431
|
+
data = Q_(float(self.data[0][0]), self.units)
|
|
2432
|
+
return data.m_as(units)
|
|
2433
|
+
else:
|
|
2434
|
+
return float(self.data[0][0])
|
|
2421
2435
|
else:
|
|
2422
|
-
|
|
2436
|
+
if units is not None:
|
|
2437
|
+
data = Q_(float(np.mean(self.data[0])), self.units)
|
|
2438
|
+
return data.m_as(units)
|
|
2439
|
+
else:
|
|
2440
|
+
return float(np.mean(self.data[0]))
|
|
2423
2441
|
|
|
2424
|
-
def values(self) -> List[float]:
|
|
2442
|
+
def values(self, units: str = None) -> List[float]:
|
|
2425
2443
|
"""Returns the underlying float value (for each data array in the data list) if this data
|
|
2426
2444
|
holds only a float otherwise returns a mean of the underlying data"""
|
|
2427
2445
|
if self.length == 1 and self.size == 1:
|
|
2428
|
-
|
|
2446
|
+
if units is not None:
|
|
2447
|
+
return [float(Q_(data_array[0], self.units).m_as(units))
|
|
2448
|
+
for data_array in self.data]
|
|
2449
|
+
else:
|
|
2450
|
+
return [float(data_array[0])
|
|
2451
|
+
for data_array in self.data]
|
|
2429
2452
|
else:
|
|
2430
|
-
|
|
2453
|
+
if units is not None:
|
|
2454
|
+
return [float(Q_(np.mean(data_array), self.units).m_as(units))
|
|
2455
|
+
for data_array in self.data]
|
|
2456
|
+
else:
|
|
2457
|
+
return [float(np.mean(data_array)) for data_array in self.data]
|
|
2431
2458
|
|
|
2432
2459
|
|
|
2433
2460
|
class DataFromPlugins(DataRaw):
|
|
@@ -12,7 +12,7 @@ def load_dashboard_with_preset(preset_name: str, extension_name: str):
|
|
|
12
12
|
area = DockArea()
|
|
13
13
|
win.setCentralWidget(area)
|
|
14
14
|
win.resize(1000, 500)
|
|
15
|
-
win.setWindowTitle('
|
|
15
|
+
win.setWindowTitle('extension_name')
|
|
16
16
|
win.show()
|
|
17
17
|
|
|
18
18
|
# win.setVisible(False)
|
|
@@ -420,6 +420,7 @@ class Serializer:
|
|
|
420
420
|
* serialize the string type: 'DataWithAxes'
|
|
421
421
|
* serialize the timestamp: float
|
|
422
422
|
* serialize the name
|
|
423
|
+
* serialize the units
|
|
423
424
|
* serialize the source enum as a string
|
|
424
425
|
* serialize the dim enum as a string
|
|
425
426
|
* serialize the distribution enum as a string
|
|
@@ -439,6 +440,7 @@ class Serializer:
|
|
|
439
440
|
bytes_string += self.object_type_serialization(dwa)
|
|
440
441
|
bytes_string += self.scalar_serialization(dwa.timestamp)
|
|
441
442
|
bytes_string += self.string_serialization(dwa.name)
|
|
443
|
+
bytes_string += self.string_serialization(dwa.units)
|
|
442
444
|
bytes_string += self.string_serialization(dwa.source.name)
|
|
443
445
|
bytes_string += self.string_serialization(dwa.dim.name)
|
|
444
446
|
bytes_string += self.string_serialization(dwa.distribution.name)
|
|
@@ -731,9 +733,11 @@ class DeSerializer:
|
|
|
731
733
|
"""
|
|
732
734
|
class_name = self.string_deserialization()
|
|
733
735
|
if class_name not in DwaType.names():
|
|
734
|
-
raise TypeError(f'Attempting to deserialize a DataWithAxes
|
|
736
|
+
raise TypeError(f'Attempting to deserialize a DataWithAxes '
|
|
737
|
+
f'flavor but got the bytes for a {class_name}')
|
|
735
738
|
timestamp = self.scalar_deserialization()
|
|
736
739
|
dwa = getattr(data_mod, class_name)(self.string_deserialization(),
|
|
740
|
+
units=self.string_deserialization(),
|
|
737
741
|
source=self.string_deserialization(),
|
|
738
742
|
dim=self.string_deserialization(),
|
|
739
743
|
distribution=self.string_deserialization(),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pymodaq
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.2
|
|
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
|
|
@@ -77,7 +77,7 @@ PyMoDAQ
|
|
|
77
77
|
:target: https://pymodaq.readthedocs.io/en/stable/?badge=latest
|
|
78
78
|
:alt: Documentation Status
|
|
79
79
|
|
|
80
|
-
.. image:: https://codecov.io/gh/PyMoDAQ/PyMoDAQ/branch/
|
|
80
|
+
.. image:: https://codecov.io/gh/PyMoDAQ/PyMoDAQ/branch/4.4.x/graph/badge.svg?token=IQNJRCQDM2
|
|
81
81
|
:target: https://codecov.io/gh/PyMoDAQ/PyMoDAQ
|
|
82
82
|
|
|
83
83
|
====== ========== ======= ======
|
|
@@ -93,25 +93,25 @@ Python Qt Backend OS Passed
|
|
|
93
93
|
====== ========== ======= ======
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
.. |38Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5.yml/badge.svg?branch=4.
|
|
96
|
+
.. |38Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5.yml/badge.svg?branch=4.4.x
|
|
97
97
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5.yml
|
|
98
98
|
|
|
99
|
-
.. |39Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt5.yml/badge.svg?branch=4.
|
|
99
|
+
.. |39Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt5.yml/badge.svg?branch=4.4.x
|
|
100
100
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt5.yml
|
|
101
101
|
|
|
102
|
-
.. |310Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp310pyqt5.yml/badge.svg?branch=4.
|
|
102
|
+
.. |310Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp310pyqt5.yml/badge.svg?branch=4.4.x
|
|
103
103
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp310pyqt5.yml
|
|
104
104
|
|
|
105
|
-
.. |311Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp311pyqt5.yml/badge.svg?branch=4.
|
|
105
|
+
.. |311Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp311pyqt5.yml/badge.svg?branch=4.4.x
|
|
106
106
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp311pyqt5.yml
|
|
107
107
|
|
|
108
|
-
.. |38Qt5win| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5_win.yml/badge.svg?branch=4.
|
|
108
|
+
.. |38Qt5win| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5_win.yml/badge.svg?branch=4.4.x
|
|
109
109
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5_win.yml
|
|
110
110
|
|
|
111
|
-
.. |38pyside| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyside2.yml/badge.svg?branch=4.
|
|
111
|
+
.. |38pyside| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyside2.yml/badge.svg?branch=4.4.x
|
|
112
112
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyside2.yml
|
|
113
113
|
|
|
114
|
-
.. |39Qt6| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt6.yml/badge.svg?branch=4.
|
|
114
|
+
.. |39Qt6| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt6.yml/badge.svg?branch=4.4.x
|
|
115
115
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt6.yml
|
|
116
116
|
|
|
117
117
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
pymodaq/__init__.py,sha256=
|
|
1
|
+
pymodaq/__init__.py,sha256=e4pcKgxrhCVtCuq3t-gcfkwCWtV72K6jhPa-0zAtRfs,4382
|
|
2
2
|
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=
|
|
7
|
-
pymodaq/control_modules/daq_move_ui.py,sha256=
|
|
6
|
+
pymodaq/control_modules/daq_move.py,sha256=L4lW_VfdBKmrlpLkKwbNitDeLHbFWk6Lbq4T5k-6xiM,37323
|
|
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=WwZku-xFsyqun25IG9570_OU5x1frA9rIrxVu6XJKIk,42599
|
|
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
|
|
@@ -16,7 +16,7 @@ pymodaq/examples/custom_app.py,sha256=2wQR0hlPWjZrWK0abNF6ASv8iQyJqRn2CKnBa_nAgN
|
|
|
16
16
|
pymodaq/examples/custom_viewer.py,sha256=nUj5n6l7DSyh-qaXboNBfXKa9mAiXrHSiOcuFL1ayRE,4814
|
|
17
17
|
pymodaq/examples/function_plotter.py,sha256=T-VT0Rd3jHP9GcR2h6Nao6lwZE06P8zWUbOlz8b8Rxk,6104
|
|
18
18
|
pymodaq/examples/nonlinearscanner.py,sha256=x0R2_FP0YnuOCCAmYRiAiZ1jfUdRxu5RqIYLyGQMZ0U,3790
|
|
19
|
-
pymodaq/examples/parameter_ex.py,sha256=
|
|
19
|
+
pymodaq/examples/parameter_ex.py,sha256=NmFUvUByNtm3j4leN_MkufQsKlNU8Rx5lmpsVG58IIM,8556
|
|
20
20
|
pymodaq/examples/preset_MockCamera.xml,sha256=quQlMsX6YSoqqc9_9Y-9zu3TDM6Xvnuc2JSWwg9f948,15774
|
|
21
21
|
pymodaq/examples/tcp_client.py,sha256=FSdPlb3R_rxxNIqPqHVU8PxJzNZeFk_93l4TqsB5SnA,2584
|
|
22
22
|
pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.aliases,sha256=t0eKH9Uq_AMk4wQ-6Pm5mKUjGcCvfT9GtvMsvDhkCUk,47
|
|
@@ -58,7 +58,7 @@ pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py,sha256=1u7hWDaiwsZ
|
|
|
58
58
|
pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui,sha256=PyzbCWPMkh5oIYYteZczXyWMeHKW9EJmM1QlzXhnyTk,7037
|
|
59
59
|
pymodaq/post_treatment/daq_measurement/daq_measurement_main.py,sha256=CAKwcWMOD86aXB8mbdxOK7e8nZRos5d59FzDtqK1QoY,17093
|
|
60
60
|
pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat,sha256=e1tu2A67MS9fk3jhriF6saQgRxWIucIvNW92iWXFP6E,164
|
|
61
|
-
pymodaq/resources/VERSION,sha256=
|
|
61
|
+
pymodaq/resources/VERSION,sha256=u7UAa-_KS1Q9ODCq7-42m4PKdNLnm3M_qQLvikeM9Hc,19
|
|
62
62
|
pymodaq/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
63
|
pymodaq/resources/config_template.toml,sha256=d3pofgIK5FxaRMELAI1qEsRcMD3GlYd87zZjDj9G9m0,3210
|
|
64
64
|
pymodaq/resources/preset_default.xml,sha256=Dt8iWLwPPOPtcG00JCVP-mh-G7KC6B0YN8hd8RQdnNI,27256
|
|
@@ -308,10 +308,10 @@ pymodaq/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
308
308
|
pymodaq/utils/array_manipulation.py,sha256=uMdiVVR2mU7j6Z4DKL5VGhUPqiWvFX2YK7RLMGdLyC8,10415
|
|
309
309
|
pymodaq/utils/calibration_camera.py,sha256=d3aAu0izXOdeLs-vyBaFfBuvyDGT3O-SreTuyd0Kvs4,8921
|
|
310
310
|
pymodaq/utils/chrono_timer.py,sha256=rwX8apS8B-IKhA0Cp2H9tLz0BRN7G3Pg5ptozvd3MKM,7244
|
|
311
|
-
pymodaq/utils/config.py,sha256=
|
|
311
|
+
pymodaq/utils/config.py,sha256=0QqoBJC4ECuIeh1UsvUQqhxkKl7Vfgi4iERp-6qNWAc,16202
|
|
312
312
|
pymodaq/utils/conftests.py,sha256=3Ak8WEpa3EhAp73Yb1LLq8YFONhPqiL7gG9eSDIoTNc,58
|
|
313
313
|
pymodaq/utils/daq_utils.py,sha256=0jTrbT0aaZr3KaTgeDicmK9FbVnu3iaWBmNHnNJpr3A,28050
|
|
314
|
-
pymodaq/utils/data.py,sha256=
|
|
314
|
+
pymodaq/utils/data.py,sha256=V4F_H-sUPmCwrcNDuF7JxzcJtnOlQX7fChSoyXdd6ng,111572
|
|
315
315
|
pymodaq/utils/enums.py,sha256=wpRipioUJkKcEfoaY2NrDQ2WhGxZTZiZoJty5f2Ljpc,2236
|
|
316
316
|
pymodaq/utils/exceptions.py,sha256=wLO6VlofzfwWkOOWMN2B-3NEWMfpgygyeEdakIx_rAs,668
|
|
317
317
|
pymodaq/utils/factory.py,sha256=QLqAPFnTZ93eUpmAAIr7kESDk2enD57RNSuFUsjxE4E,2311
|
|
@@ -333,7 +333,7 @@ pymodaq/utils/gui_utils/dock.py,sha256=6AcxC9HqM45bt20vJgP6QgGAhkW8mynuOuWhL7gep
|
|
|
333
333
|
pymodaq/utils/gui_utils/file_io.py,sha256=mJI_30p986rLZk44FsPjesMazE1tq7HEFLenW-dnmOI,3367
|
|
334
334
|
pymodaq/utils/gui_utils/layout.py,sha256=6oczLLGwwEN4EQ8yUDnz0-4Ue2wlyCRklKsVD1GNcz8,1099
|
|
335
335
|
pymodaq/utils/gui_utils/list_picker.py,sha256=ddYnRTlRlgwdJSy0Q98IzYWHzIf2GS6ABl8XSS9kVXM,1190
|
|
336
|
-
pymodaq/utils/gui_utils/loader_utils.py,sha256=
|
|
336
|
+
pymodaq/utils/gui_utils/loader_utils.py,sha256=Gg0d31fjkqDq3l1WuRMbLzKiKPOIYdbUrcfGOgoXRk0,1298
|
|
337
337
|
pymodaq/utils/gui_utils/utils.py,sha256=aPxFCnG4skDp-0UuhAudq6BPZnEXoAf6FOEJyrhUjx0,6089
|
|
338
338
|
pymodaq/utils/gui_utils/widgets/__init__.py,sha256=LThGzmbFKbp2FtTTF_L7pHjyBzfB7F_bhMF4rPTwrUY,195
|
|
339
339
|
pymodaq/utils/gui_utils/widgets/label.py,sha256=C2MU8i_Yy_oVRW7yal_ghB1Y5Bj_a9o8IFZWW3br-KM,600
|
|
@@ -436,10 +436,10 @@ pymodaq/utils/svg/svg_view.py,sha256=bmXpDqnw9S-Bp3F8Hi_oeYB5Y9gebiCNsQWVJzCq-PA
|
|
|
436
436
|
pymodaq/utils/svg/svg_viewer2D.py,sha256=LTJ3Ulb5zWXdRPr7vqcWumbpq7ZctzrYUMtD5QV3x60,1523
|
|
437
437
|
pymodaq/utils/tcp_ip/__init__.py,sha256=1e_EK0AgvdoLAD_CSGGEaITZdy6OWCO7ih9IAIp7HT4,81
|
|
438
438
|
pymodaq/utils/tcp_ip/mysocket.py,sha256=StAWj8dzHeMnbLj68Sel81uWFy-YkKVNRnVf7gXrESI,3452
|
|
439
|
-
pymodaq/utils/tcp_ip/serializer.py,sha256=
|
|
439
|
+
pymodaq/utils/tcp_ip/serializer.py,sha256=htVQCE4saRBMeIcseEyxTt5G58A341m6OGkaJUA34Wk,27766
|
|
440
440
|
pymodaq/utils/tcp_ip/tcp_server_client.py,sha256=xIMTNgVW_rKK0yTi4FDNFLf85-Akb27Jz2LdrvOrP68,30660
|
|
441
|
-
pymodaq-4.
|
|
442
|
-
pymodaq-4.
|
|
443
|
-
pymodaq-4.
|
|
444
|
-
pymodaq-4.
|
|
445
|
-
pymodaq-4.
|
|
441
|
+
pymodaq-4.4.2.dist-info/METADATA,sha256=wc6QZZgW3pBAs85kQQ88JdPtJ8omKojHa1RDSgtuR3s,7623
|
|
442
|
+
pymodaq-4.4.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
443
|
+
pymodaq-4.4.2.dist-info/entry_points.txt,sha256=RAzdYNjvUT28I2eiCKki_g2NzXq0woWxhev6lwzwRv8,348
|
|
444
|
+
pymodaq-4.4.2.dist-info/licenses/LICENSE,sha256=VKOejxexXAe3XwfhAhcFGqeXQ12irxVHdeAojZwFEI8,1108
|
|
445
|
+
pymodaq-4.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|