pymodaq 4.4.6__py3-none-any.whl → 4.4.7__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/resources/VERSION CHANGED
@@ -1,2 +1,2 @@
1
- version = '4.4.6'
1
+ version = '4.4.7'
2
2
 
pymodaq/utils/data.py CHANGED
@@ -98,6 +98,7 @@ class DataUnitError(Exception):
98
98
 
99
99
 
100
100
  class DwaType(BaseEnum):
101
+ """Different types of `DataWithAxes`."""
101
102
  DataWithAxes = 0
102
103
  DataRaw = 1
103
104
  DataActuator = 2
@@ -17,7 +17,7 @@ logger = set_logger(get_module_name(__file__))
17
17
  remote_path = pymodaq.utils.config.get_set_remote_path()
18
18
  remote_types = ['ShortCut', 'Joystick']
19
19
 
20
- actuator_actions = ['move_Rel', 'move_Rel_p', 'move_Rel_m']
20
+ actuator_actions = ['move_rel', 'move_rel_p', 'move_rel_m']
21
21
  detector_actions = ['snap', 'grab', 'stop']
22
22
  remote_types = ['Keyboard', 'Joystick']
23
23
  try:
@@ -5,8 +5,9 @@ Created the 20/10/2023
5
5
  @author: Sebastien Weber
6
6
  """
7
7
  from base64 import b64encode, b64decode
8
+ from enum import Enum
8
9
  import numbers
9
- from typing import Tuple, List, Union, TYPE_CHECKING, Iterable
10
+ from typing import Optional, Tuple, List, Union, TYPE_CHECKING
10
11
 
11
12
 
12
13
  import numpy as np
@@ -20,17 +21,38 @@ if TYPE_CHECKING:
20
21
 
21
22
 
22
23
  SERIALIZABLE = Union[
23
- int,
24
+ # native
25
+ bool,
26
+ bytes,
24
27
  str,
25
- numbers.Number,
28
+ complex, # float and int are subtypes for type hinting
29
+ float,
30
+ int,
26
31
  list,
32
+ # numpy
27
33
  np.ndarray,
34
+ # pymodaq
28
35
  Axis,
29
36
  DataWithAxes,
30
37
  DataToExport,
38
+ putils.ParameterWithPath,
31
39
  ]
32
40
 
33
41
 
42
+ class SerializableTypes(Enum):
43
+ """Type names of serializable types"""
44
+ BOOL = "bool"
45
+ BYTES = "bytes"
46
+ STRING = "string"
47
+ SCALAR = "scalar"
48
+ LIST = "list"
49
+ ARRAY = "array"
50
+ AXIS = "axis"
51
+ DATA_WITH_AXES = "dwa"
52
+ DATA_TO_EXPORT = "dte"
53
+ PARAMETER = "parameter"
54
+
55
+
34
56
  class SocketString:
35
57
  """Mimic the Socket object but actually using a bytes string not a socket connection
36
58
 
@@ -86,7 +108,7 @@ class Serializer:
86
108
  """Used to Serialize to bytes python objects, numpy arrays and PyMoDAQ DataWithAxes and
87
109
  DataToExport objects"""
88
110
 
89
- def __init__(self, obj: SERIALIZABLE = None):
111
+ def __init__(self, obj: Optional[SERIALIZABLE] = None) -> None:
90
112
  self._bytes_string = b''
91
113
  self._obj = obj
92
114
 
@@ -154,7 +176,7 @@ class Serializer:
154
176
  return message.encode()
155
177
 
156
178
  @classmethod
157
- def str_len_to_bytes(cls, message: Union[str, bytes]) -> (bytes, bytes):
179
+ def str_len_to_bytes(cls, message: Union[str, bytes]) -> Tuple[bytes, bytes]:
158
180
  """ Convert a string and its length to two bytes
159
181
  Parameters
160
182
  ----------
@@ -174,7 +196,7 @@ class Serializer:
174
196
  return message, cls.int_to_bytes(len(message))
175
197
 
176
198
  def _int_serialization(self, int_obj: int) -> bytes:
177
- """serialize an unsigned integer used for getting the length of messages internaly, for outside integer
199
+ """Serialize an unsigned integer used for getting the length of messages internally, for outside integer
178
200
  serialization or deserialization use scalar_serialization"""
179
201
  int_bytes = self.int_to_bytes(int_obj)
180
202
  bytes_string = int_bytes
@@ -205,18 +227,19 @@ class Serializer:
205
227
  self._bytes_string += bytes_string
206
228
  return bytes_string
207
229
 
208
- def scalar_serialization(self, scalar: numbers.Number) -> bytes:
230
+ def scalar_serialization(self, scalar: complex) -> bytes:
209
231
  """ Convert a scalar into a bytes message together with the info to convert it back
210
232
 
211
233
  Parameters
212
234
  ----------
213
- scalar: str
235
+ scalar: A python number (complex or subtypes like float and int)
214
236
 
215
237
  Returns
216
238
  -------
217
239
  bytes: the total bytes message to serialize the scalar
218
240
  """
219
241
  if not isinstance(scalar, numbers.Number):
242
+ # type hint is complex, instance comparison Number
220
243
  raise TypeError(f'{scalar} should be an integer or a float, not a {type(scalar)}')
221
244
  scalar_array = np.array([scalar])
222
245
  data_type = scalar_array.dtype.descr[0][1]
@@ -350,49 +373,56 @@ class Serializer:
350
373
  self._bytes_string += bytes_string
351
374
  return bytes_string
352
375
 
353
- def type_and_object_serialization(self, obj):
376
+ def type_and_object_serialization(self, obj: Optional[SERIALIZABLE] = None) -> bytes:
377
+ """Serialize an object with its type, such that it can be retrieved by
378
+ `DeSerializer.type_and_object_deserialization`.
379
+ """
380
+
381
+ if obj is None and self._obj is not None:
382
+ obj = self._obj
383
+
354
384
  bytes_string = b''
355
385
  if isinstance(obj, DataWithAxes):
356
- bytes_string += self.string_serialization('dwa')
386
+ bytes_string += self.string_serialization(SerializableTypes.DATA_WITH_AXES.value)
357
387
  bytes_string += self.dwa_serialization(obj)
358
388
 
359
389
  elif isinstance(obj, Axis):
360
- bytes_string += self.string_serialization('axis')
390
+ bytes_string += self.string_serialization(SerializableTypes.AXIS.value)
361
391
  bytes_string += self.axis_serialization(obj)
362
392
 
363
393
  elif isinstance(obj, np.ndarray):
364
- bytes_string += self.string_serialization('array')
394
+ bytes_string += self.string_serialization(SerializableTypes.ARRAY.value)
365
395
  bytes_string += self.ndarray_serialization(obj)
366
396
 
367
397
  elif isinstance(obj, bytes):
368
- bytes_string += self.string_serialization('bytes')
398
+ bytes_string += self.string_serialization(SerializableTypes.BYTES.value)
369
399
  bytes_string += self.bytes_serialization(obj)
370
400
 
371
401
  elif isinstance(obj, str):
372
- bytes_string += self.string_serialization('string')
402
+ bytes_string += self.string_serialization(SerializableTypes.STRING.value)
373
403
  bytes_string += self.string_serialization(obj)
374
404
 
375
- elif isinstance(obj, numbers.Number):
376
- bytes_string += self.string_serialization('scalar')
405
+ elif isinstance(obj, bool):
406
+ bytes_string += self.string_serialization(SerializableTypes.BOOL.value)
377
407
  bytes_string += self.scalar_serialization(obj)
378
408
 
379
- elif isinstance(obj, bool):
380
- bytes_string += self.string_serialization('bool')
381
- bytes_string += self.scalar_serialization(int(obj))
409
+ elif isinstance(obj, numbers.Number):
410
+ bytes_string += self.string_serialization(SerializableTypes.SCALAR.value)
411
+ bytes_string += self.scalar_serialization(obj)
382
412
 
383
413
  elif isinstance(obj, list):
384
- bytes_string += self.string_serialization('list')
414
+ bytes_string += self.string_serialization(SerializableTypes.LIST.value)
385
415
  bytes_string += self.list_serialization(obj)
386
416
 
387
417
  elif isinstance(obj, putils.ParameterWithPath):
388
418
  path = obj.path
389
419
  param_as_xml = ioxml.parameter_to_xml_string(obj.parameter)
390
- bytes_string += self.string_serialization('parameter')
420
+ bytes_string += self.string_serialization(SerializableTypes.PARAMETER.value)
391
421
  bytes_string += self.list_serialization(path)
392
- bytes_string += self.string_serialization(param_as_xml)
422
+ bytes_string += self.bytes_serialization(param_as_xml)
393
423
 
394
424
  elif isinstance(obj, DataToExport):
395
- bytes_string += self.string_serialization('dte')
425
+ bytes_string += self.string_serialization(SerializableTypes.DATA_TO_EXPORT.value)
396
426
  bytes_string += self.dte_serialization(obj)
397
427
 
398
428
  else:
@@ -509,7 +539,7 @@ class DeSerializer:
509
539
  :py:class:`~pymodaq.utils.tcp_ip.mysocket.Socket`
510
540
  """
511
541
 
512
- def __init__(self, bytes_string: Union[bytes, 'Socket'] = None):
542
+ def __init__(self, bytes_string: Union[bytes, 'Socket'] = None) -> None:
513
543
  if isinstance(bytes_string, bytes):
514
544
  bytes_string = SocketString(bytes_string)
515
545
  self._bytes_string = bytes_string
@@ -531,7 +561,7 @@ class DeSerializer:
531
561
  return int.from_bytes(bytes_string, 'big')
532
562
 
533
563
  @staticmethod
534
- def bytes_to_scalar(data: bytes, dtype: np.dtype) -> numbers.Number:
564
+ def bytes_to_scalar(data: bytes, dtype: np.dtype) -> complex:
535
565
  """Convert bytes to a scalar given a certain numpy dtype
536
566
 
537
567
  Parameters
@@ -588,8 +618,8 @@ class DeSerializer:
588
618
  str_obj = self._bytes_string.get_first_nbytes(string_len).decode()
589
619
  return str_obj
590
620
 
591
- def scalar_deserialization(self) -> numbers.Number:
592
- """Convert bytes into a numbers.Number object
621
+ def scalar_deserialization(self) -> complex:
622
+ """Convert bytes into a python number object
593
623
 
594
624
  Get first the data type from a string deserialization, then the data length and finally convert this
595
625
  length of bytes into a number (float, int)
@@ -602,9 +632,11 @@ class DeSerializer:
602
632
  data_len = self._int_deserialization()
603
633
  number = np.frombuffer(self._bytes_string.get_first_nbytes(data_len), dtype=data_type)[0]
604
634
  if 'f' in data_type:
605
- number = float(number) # because one get numpy float type
635
+ number = float(number) # because one get numpy float type
606
636
  elif 'i' in data_type:
607
637
  number = int(number) # because one get numpy int type
638
+ elif 'c' in data_type:
639
+ number = complex(number) # because one get numpy complex type
608
640
  return number
609
641
 
610
642
  def boolean_deserialization(self) -> bool:
@@ -642,7 +674,7 @@ class DeSerializer:
642
674
  ndarray = np.atleast_1d(ndarray) # remove singleton dimensions
643
675
  return ndarray
644
676
 
645
- def type_and_object_deserialization(self):
677
+ def type_and_object_deserialization(self) -> SERIALIZABLE:
646
678
  """ Deserialize specific objects from their binary representation (inverse of `Serializer.type_and_object_serialization`).
647
679
 
648
680
  See Also
@@ -652,28 +684,29 @@ class DeSerializer:
652
684
  """
653
685
  obj_type = self.string_deserialization()
654
686
  elt = None
655
- if obj_type == 'scalar':
687
+ if obj_type == SerializableTypes.SCALAR.value:
656
688
  elt = self.scalar_deserialization()
657
- elif obj_type == 'string':
689
+ elif obj_type == SerializableTypes.STRING.value:
658
690
  elt = self.string_deserialization()
659
- elif obj_type == 'bytes':
691
+ elif obj_type == SerializableTypes.BYTES.value:
660
692
  elt = self.bytes_deserialization()
661
- elif obj_type == 'array':
693
+ elif obj_type == SerializableTypes.ARRAY.value:
662
694
  elt = self.ndarray_deserialization()
663
- elif obj_type == 'dwa':
695
+ elif obj_type == SerializableTypes.DATA_WITH_AXES.value:
664
696
  elt = self.dwa_deserialization()
665
- elif obj_type == 'dte':
697
+ elif obj_type == SerializableTypes.DATA_TO_EXPORT.value:
666
698
  elt = self.dte_deserialization()
667
- elif obj_type == 'axis':
699
+ elif obj_type == SerializableTypes.AXIS.value:
668
700
  elt = self.axis_deserialization()
669
- elif obj_type == 'bool':
701
+ elif obj_type == SerializableTypes.BOOL.value:
670
702
  elt = self.boolean_deserialization()
671
- elif obj_type == 'list':
703
+ elif obj_type == SerializableTypes.LIST.value:
672
704
  elt = self.list_deserialization()
673
- elif obj_type == 'parameter':
705
+ elif obj_type == SerializableTypes.PARAMETER.value:
674
706
  elt = self.parameter_deserialization()
675
707
  else:
676
708
  print(f'invalid object type {obj_type}')
709
+ elt = None # desired behavior?
677
710
  return elt
678
711
 
679
712
  def list_deserialization(self) -> list:
@@ -774,4 +807,4 @@ class DeSerializer:
774
807
  data=self.list_deserialization(),
775
808
  )
776
809
  dte.timestamp = timestamp
777
- return dte
810
+ return dte
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pymodaq
3
- Version: 4.4.6
3
+ Version: 4.4.7
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
@@ -27,7 +27,6 @@ License: The MIT License (MIT)
27
27
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
28
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
29
  THE SOFTWARE.
30
- License-File: LICENSE
31
30
  Classifier: Development Status :: 5 - Production/Stable
32
31
  Classifier: Environment :: Other Environment
33
32
  Classifier: Intended Audience :: Science/Research
@@ -44,7 +43,7 @@ Classifier: Topic :: Scientific/Engineering :: Visualization
44
43
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
45
44
  Classifier: Topic :: Software Development :: User Interfaces
46
45
  Requires-Python: >=3.7
47
- Requires-Dist: bayesian-optimization
46
+ Requires-Dist: bayesian-optimization<2.0.0
48
47
  Requires-Dist: easydict
49
48
  Requires-Dist: importlib-metadata; python_version < '3.8'
50
49
  Requires-Dist: multipledispatch
@@ -59,7 +59,7 @@ pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py,sha256=1u7hWDaiwsZ
59
59
  pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui,sha256=PyzbCWPMkh5oIYYteZczXyWMeHKW9EJmM1QlzXhnyTk,7037
60
60
  pymodaq/post_treatment/daq_measurement/daq_measurement_main.py,sha256=CAKwcWMOD86aXB8mbdxOK7e8nZRos5d59FzDtqK1QoY,17093
61
61
  pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat,sha256=e1tu2A67MS9fk3jhriF6saQgRxWIucIvNW92iWXFP6E,164
62
- pymodaq/resources/VERSION,sha256=WLq0vLL18vLMV1jwQsziDmyw7JVoEVuWAB0pDGzYEvM,19
62
+ pymodaq/resources/VERSION,sha256=ib4rQ9G3YTfdijgNEWBcOoAIZQyUy-mfF0jvGog9fno,19
63
63
  pymodaq/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
64
  pymodaq/resources/config_template.toml,sha256=d3pofgIK5FxaRMELAI1qEsRcMD3GlYd87zZjDj9G9m0,3210
65
65
  pymodaq/resources/preset_default.xml,sha256=Dt8iWLwPPOPtcG00JCVP-mh-G7KC6B0YN8hd8RQdnNI,27256
@@ -312,7 +312,7 @@ pymodaq/utils/chrono_timer.py,sha256=rwX8apS8B-IKhA0Cp2H9tLz0BRN7G3Pg5ptozvd3MKM
312
312
  pymodaq/utils/config.py,sha256=0QqoBJC4ECuIeh1UsvUQqhxkKl7Vfgi4iERp-6qNWAc,16202
313
313
  pymodaq/utils/conftests.py,sha256=3Ak8WEpa3EhAp73Yb1LLq8YFONhPqiL7gG9eSDIoTNc,58
314
314
  pymodaq/utils/daq_utils.py,sha256=0jTrbT0aaZr3KaTgeDicmK9FbVnu3iaWBmNHnNJpr3A,28050
315
- pymodaq/utils/data.py,sha256=rasOk1-2o8fJHE_zm7ygrWXL7cBOHJOgwWMZhbVG7z0,111863
315
+ pymodaq/utils/data.py,sha256=RdzEDz3ziRmwbaqy875fLr06jrmaG1wzU-0e_5QQKXM,111908
316
316
  pymodaq/utils/enums.py,sha256=wpRipioUJkKcEfoaY2NrDQ2WhGxZTZiZoJty5f2Ljpc,2236
317
317
  pymodaq/utils/exceptions.py,sha256=wLO6VlofzfwWkOOWMN2B-3NEWMfpgygyeEdakIx_rAs,668
318
318
  pymodaq/utils/factory.py,sha256=QLqAPFnTZ93eUpmAAIr7kESDk2enD57RNSuFUsjxE4E,2311
@@ -374,7 +374,7 @@ pymodaq/utils/managers/overshoot_manager.py,sha256=fe_CR1Bkw85BER34MoVFlm-xtKl9H
374
374
  pymodaq/utils/managers/parameter_manager.py,sha256=hO3RXcpkYOtuqjAQaD5H3r71rVEHntYg64VHZwVCQBg,11473
375
375
  pymodaq/utils/managers/preset_manager.py,sha256=m8r_TcfFbUatddBX9SJj7XI_GZ3FhoiwzhFgocw9jZ8,9481
376
376
  pymodaq/utils/managers/preset_manager_utils.py,sha256=d148YBjeNOP9FTkFoTsfdRDxMIXOR8JJHqbOmoL2aVA,8155
377
- pymodaq/utils/managers/remote_manager.py,sha256=H6k9aiBkuJRJbZ4rpd5jfawQ-pMRFAXOE_miakvciP8,22251
377
+ pymodaq/utils/managers/remote_manager.py,sha256=SwzefJuGpgzvvjTbJSo3T3Rc2rncvHHyPYPBd8gCQX8,22251
378
378
  pymodaq/utils/managers/roi_manager.py,sha256=RRICNSLMxiUoq8tEBKihpdydIVAu78ogkYOFWWphaHE,29892
379
379
  pymodaq/utils/parameter/__init__.py,sha256=fMljZeQ9EVvh2bmss550C5BpxFeKOxT8_AVJdPxQ0kQ,433
380
380
  pymodaq/utils/parameter/ioxml.py,sha256=jduHhMrpc0lkSJlznnI-LRHUJ0Ofc4PoFfNlxLbLmw8,17091
@@ -437,10 +437,10 @@ pymodaq/utils/svg/svg_view.py,sha256=bmXpDqnw9S-Bp3F8Hi_oeYB5Y9gebiCNsQWVJzCq-PA
437
437
  pymodaq/utils/svg/svg_viewer2D.py,sha256=LTJ3Ulb5zWXdRPr7vqcWumbpq7ZctzrYUMtD5QV3x60,1523
438
438
  pymodaq/utils/tcp_ip/__init__.py,sha256=1e_EK0AgvdoLAD_CSGGEaITZdy6OWCO7ih9IAIp7HT4,81
439
439
  pymodaq/utils/tcp_ip/mysocket.py,sha256=StAWj8dzHeMnbLj68Sel81uWFy-YkKVNRnVf7gXrESI,3452
440
- pymodaq/utils/tcp_ip/serializer.py,sha256=htVQCE4saRBMeIcseEyxTt5G58A341m6OGkaJUA34Wk,27766
440
+ pymodaq/utils/tcp_ip/serializer.py,sha256=kXmvFLR5ZedjY2rVGUs83lsJk9Z9l_iAWR6srDxzaYQ,29262
441
441
  pymodaq/utils/tcp_ip/tcp_server_client.py,sha256=xIMTNgVW_rKK0yTi4FDNFLf85-Akb27Jz2LdrvOrP68,30660
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,,
442
+ pymodaq-4.4.7.dist-info/METADATA,sha256=jkmtri16XiPHC-2It45CeeZp--C6giXVJ0FLp3g13u8,7611
443
+ pymodaq-4.4.7.dist-info/WHEEL,sha256=3U_NnUcV_1B1kPkYaPzN-irRckL5VW_lytn0ytO_kRY,87
444
+ pymodaq-4.4.7.dist-info/entry_points.txt,sha256=RAzdYNjvUT28I2eiCKki_g2NzXq0woWxhev6lwzwRv8,348
445
+ pymodaq-4.4.7.dist-info/licenses/LICENSE,sha256=VKOejxexXAe3XwfhAhcFGqeXQ12irxVHdeAojZwFEI8,1108
446
+ pymodaq-4.4.7.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.26.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any