pymodaq_data 5.2.0a4__tar.gz → 5.2.5__tar.gz

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.
Files changed (33) hide show
  1. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/PKG-INFO +1 -1
  2. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/data.py +38 -0
  3. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/backends.py +43 -15
  4. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/.gitignore +0 -0
  5. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/LICENSE +0 -0
  6. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/README.rst +0 -0
  7. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/pyproject.toml +0 -0
  8. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/__init__.py +0 -0
  9. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/config.py +0 -0
  10. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/__init__.py +0 -0
  11. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/browsing.py +0 -0
  12. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/data_saving.py +0 -0
  13. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/exporter.py +0 -0
  14. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/exporters/__init__.py +0 -0
  15. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/exporters/base.py +0 -0
  16. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/exporters/flimj.py +0 -0
  17. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/exporters/hyperspy.py +0 -0
  18. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/saving.py +0 -0
  19. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/swmr.py +0 -0
  20. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/h5modules/utils.py +0 -0
  21. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/icon.ico +0 -0
  22. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/numpy_func.py +0 -0
  23. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/plotting/__init__.py +0 -0
  24. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/plotting/plotter/plotter.py +0 -0
  25. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/plotting/plotter/plotters/__init__.py +0 -0
  26. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/plotting/plotter/plotters/matplotlib_plotters.py +0 -0
  27. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/plotting/utils.py +0 -0
  28. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/post_treatment/__init__.py +0 -0
  29. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/post_treatment/process_to_scalar.py +0 -0
  30. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/resources/__init__.py +0 -0
  31. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/resources/config_template.toml +0 -0
  32. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/slicing.py +0 -0
  33. {pymodaq_data-5.2.0a4 → pymodaq_data-5.2.5}/src/pymodaq_data/splash.png +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymodaq_data
3
- Version: 5.2.0a4
3
+ Version: 5.2.5
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
@@ -9,6 +9,7 @@ from __future__ import annotations
9
9
  from abc import ABCMeta, abstractmethod
10
10
  from copy import deepcopy
11
11
  import numbers
12
+ import re
12
13
 
13
14
  import numpy as np
14
15
  from numpy.lib.mixins import NDArrayOperatorsMixin
@@ -46,6 +47,32 @@ plotter_factory = PlotterFactory()
46
47
  ser_factory = SerializableFactory()
47
48
  logger = set_logger(get_module_name(__file__))
48
49
 
50
+
51
+
52
+
53
+ def parse_quantity(quantity: str) -> Q_:
54
+ """
55
+ Converts a string into a Pint Quantity object using
56
+ a regex to split it in two parts and force usage of
57
+ Q_(value, unit) constructor as Q_(value_unit_str)
58
+ induces some errors.
59
+ Parameters
60
+ ----------
61
+ quantity: The string to convert
62
+
63
+ Returns
64
+ -------
65
+ The Quantity object
66
+
67
+ """
68
+ match = re.match(r'^([+-]?\d*\.?\d*(?:[eE][+-]?\d+)?)\s*(.*)$', quantity.strip())
69
+ if match:
70
+ value, unit = float(match.group(1)), match.group(2).strip()
71
+ value = float(value)
72
+ unit = unit.strip() or 'dimensionless'
73
+ return Q_(value, unit)
74
+ return Q_(quantity)
75
+
49
76
  def dimensionless_aware_reduce_units(q: Type[Q_]) -> Type[Q_]:
50
77
  """
51
78
  Take a quantity q and converts it to its reduced units.
@@ -952,6 +979,17 @@ class DataBase(DataLowLevel, NDArrayOperatorsMixin):
952
979
  """
953
980
  return f'{self.origin}/{self.name}'
954
981
 
982
+ @staticmethod
983
+ def get_origin_name_from_full_name(full_name: str):
984
+ """ Standardize the obtention of the origin and name from the full name expression
985
+
986
+ Origin is always the first bit before the first '/' character while the name will be the remaining characters
987
+ """
988
+ name_bits = full_name.split('/')
989
+ origin = name_bits[0]
990
+ name = full_name.split(f'{origin}/')[1]
991
+ return origin, name
992
+
955
993
  def __repr__(self):
956
994
  return (f'{self.__class__.__name__} <{self.name}> '
957
995
  f'<u: {self.units}> '
@@ -901,21 +901,42 @@ class H5Backend:
901
901
  raise NodeError(f'Node {where} (name={name}) does not exist')
902
902
 
903
903
  if 'CLASS' not in self.get_attr(node):
904
- self.set_attr(node, 'CLASS', 'GROUP')
905
- return GROUP(node, self.backend)
904
+ klass = self._infer_class(node)
905
+ if self.backend == 'tables':
906
+ node._v_attrs['CLASS'] = klass
907
+ else:
908
+ node.attrs['CLASS'] = klass
906
909
  else:
907
- attr = self.get_attr(node, 'CLASS')
908
- if 'ARRAY' not in attr:
909
- return GROUP(node, self.backend)
910
- elif attr == 'CARRAY':
911
- return CARRAY(node, self.backend)
912
- elif attr == 'EARRAY':
913
- return EARRAY(node, self.backend)
914
- elif attr == 'VLARRAY':
915
- if self.get_attr(node, 'subdtype') == 'string':
916
- return StringARRAY(node, self.backend)
917
- else:
918
- return VLARRAY(node, self.backend)
910
+ klass = self.get_attr(node, 'CLASS')
911
+
912
+ if 'ARRAY' not in klass:
913
+ return GROUP(node, self.backend)
914
+ elif klass == 'CARRAY':
915
+ return CARRAY(node, self.backend)
916
+ elif klass == 'EARRAY':
917
+ return EARRAY(node, self.backend)
918
+ elif klass == 'VLARRAY':
919
+ if self.get_attr(node, 'subdtype') == 'string':
920
+ return StringARRAY(node, self.backend)
921
+ else:
922
+ return VLARRAY(node, self.backend)
923
+
924
+ def _infer_class(self, node) -> str:
925
+ """Infer the CLASS attribute of a node that is missing it
926
+
927
+ PyTables always writes a CLASS attribute on every node, but a node written
928
+ through h5py/h5pyd can be missing it (for instance an interrupted write).
929
+ Falling back to 'GROUP' regardless of the actual object type would mislabel
930
+ datasets and break further tree traversal, so infer the class from the
931
+ underlying object instead.
932
+ """
933
+ if self.backend == 'tables' or isinstance(node, self.h5_library.Group):
934
+ return 'GROUP'
935
+ if node.dtype.kind == 'O':
936
+ return 'VLARRAY'
937
+ if node.maxshape and node.maxshape[0] is None:
938
+ return 'EARRAY'
939
+ return 'CARRAY'
919
940
 
920
941
  def get_node_name(self, node):
921
942
  """return node name
@@ -990,7 +1011,11 @@ class H5Backend:
990
1011
  children[child_name] = _cls(child, self.backend)
991
1012
  else:
992
1013
  for child_name, child in where.items():
993
- klass = get_attr(child, 'CLASS', self.backend)
1014
+ try:
1015
+ klass = get_attr(child, 'CLASS', self.backend)
1016
+ except KeyError:
1017
+ klass = self._infer_class(child)
1018
+ child.attrs['CLASS'] = klass
994
1019
  if 'ARRAY' in klass:
995
1020
  _cls = getattr(mod, klass)
996
1021
  else:
@@ -1033,6 +1058,7 @@ class H5Backend:
1033
1058
  def create_carray(self, where, name, obj=None, title=''):
1034
1059
  if isinstance(where, Node):
1035
1060
  where = where.node
1061
+ title = str(title)
1036
1062
  if obj is None:
1037
1063
  raise ValueError('Data to be saved as carray cannot be None')
1038
1064
  dtype = obj.dtype
@@ -1061,6 +1087,7 @@ class H5Backend:
1061
1087
  """
1062
1088
  if isinstance(where, Node):
1063
1089
  where = where.node
1090
+ title = str(title)
1064
1091
  dtype = np.dtype(dtype)
1065
1092
  shape = [0]
1066
1093
  if data_shape is not None:
@@ -1111,6 +1138,7 @@ class H5Backend:
1111
1138
  """
1112
1139
  if isinstance(where, Node):
1113
1140
  where = where.node
1141
+ title = str(title)
1114
1142
  if dtype == 'string':
1115
1143
  dtype = np.dtype(np.uint8)
1116
1144
  subdtype = 'string'
File without changes
File without changes
File without changes