pymodaq_data 5.2.10__tar.gz → 5.3.0a0__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.
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/PKG-INFO +12 -12
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/README.rst +11 -11
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/data.py +30 -8
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/backends.py +45 -7
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/data_saving.py +42 -15
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/saving.py +21 -5
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/plotting/plotter/plotters/matplotlib_plotters.py +14 -3
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/plotting/utils.py +2 -1
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/resources/config_template.toml +1 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/.gitignore +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/LICENSE +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/pyproject.toml +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/__init__.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/config.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/__init__.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/browsing.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/exporter.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/exporters/__init__.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/exporters/base.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/exporters/flimj.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/exporters/hyperspy.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/swmr.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/utils.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/icon.ico +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/numpy_func.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/plotting/__init__.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/plotting/plotter/plotter.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/plotting/plotter/plotters/__init__.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/post_treatment/__init__.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/post_treatment/process_to_scalar.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/resources/__init__.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/slicing.py +0 -0
- {pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/splash.png +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pymodaq_data
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.3.0a0
|
|
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
|
|
@@ -71,11 +71,11 @@ PyMoDAQ Data
|
|
|
71
71
|
:target: https://pypi.org/project/pymodaq_data/
|
|
72
72
|
:alt: Latest Version
|
|
73
73
|
|
|
74
|
-
.. image:: https://readthedocs.org/projects/pymodaq/badge/?version=
|
|
75
|
-
:target: https://pymodaq.readthedocs.io/en/stable/?badge=
|
|
74
|
+
.. image:: https://readthedocs.org/projects/pymodaq/badge/?version=state-machine-simplify
|
|
75
|
+
:target: https://pymodaq.readthedocs.io/en/stable/?badge=state-machine-simplify
|
|
76
76
|
:alt: Documentation Status
|
|
77
77
|
|
|
78
|
-
.. image:: https://codecov.io/gh/PyMoDAQ/PyMoDAQ/branch/
|
|
78
|
+
.. image:: https://codecov.io/gh/PyMoDAQ/PyMoDAQ/branch/state-machine-simplify/graph/badge.svg?token=IQNJRCQDM2
|
|
79
79
|
:target: https://codecov.io/gh/PyMoDAQ/PyMoDAQ
|
|
80
80
|
|
|
81
81
|
+-------------+-------------+---------------+
|
|
@@ -94,28 +94,28 @@ PyMoDAQ Data
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
.. |310-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
97
|
+
.. |310-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.10.svg
|
|
98
98
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
99
99
|
|
|
100
|
-
.. |311-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
100
|
+
.. |311-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.11.svg
|
|
101
101
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
102
102
|
|
|
103
|
-
.. |312-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
103
|
+
.. |312-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.12.svg
|
|
104
104
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
105
105
|
|
|
106
|
-
.. |313-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
106
|
+
.. |313-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.13.svg
|
|
107
107
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
108
108
|
|
|
109
|
-
.. |310-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
109
|
+
.. |310-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.10.svg
|
|
110
110
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
111
111
|
|
|
112
|
-
.. |311-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
112
|
+
.. |311-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.11.svg
|
|
113
113
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
114
114
|
|
|
115
|
-
.. |312-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
115
|
+
.. |312-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.12.svg
|
|
116
116
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
117
117
|
|
|
118
|
-
.. |313-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
118
|
+
.. |313-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.13.svg
|
|
119
119
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
120
120
|
|
|
121
121
|
|
|
@@ -11,11 +11,11 @@ PyMoDAQ Data
|
|
|
11
11
|
:target: https://pypi.org/project/pymodaq_data/
|
|
12
12
|
:alt: Latest Version
|
|
13
13
|
|
|
14
|
-
.. image:: https://readthedocs.org/projects/pymodaq/badge/?version=
|
|
15
|
-
:target: https://pymodaq.readthedocs.io/en/stable/?badge=
|
|
14
|
+
.. image:: https://readthedocs.org/projects/pymodaq/badge/?version=state-machine-simplify
|
|
15
|
+
:target: https://pymodaq.readthedocs.io/en/stable/?badge=state-machine-simplify
|
|
16
16
|
:alt: Documentation Status
|
|
17
17
|
|
|
18
|
-
.. image:: https://codecov.io/gh/PyMoDAQ/PyMoDAQ/branch/
|
|
18
|
+
.. image:: https://codecov.io/gh/PyMoDAQ/PyMoDAQ/branch/state-machine-simplify/graph/badge.svg?token=IQNJRCQDM2
|
|
19
19
|
:target: https://codecov.io/gh/PyMoDAQ/PyMoDAQ
|
|
20
20
|
|
|
21
21
|
+-------------+-------------+---------------+
|
|
@@ -34,28 +34,28 @@ PyMoDAQ Data
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
.. |310-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
37
|
+
.. |310-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.10.svg
|
|
38
38
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
39
39
|
|
|
40
|
-
.. |311-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
40
|
+
.. |311-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.11.svg
|
|
41
41
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
42
42
|
|
|
43
|
-
.. |312-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
43
|
+
.. |312-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.12.svg
|
|
44
44
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
45
45
|
|
|
46
|
-
.. |313-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
46
|
+
.. |313-linux| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Linux_3.13.svg
|
|
47
47
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
48
48
|
|
|
49
|
-
.. |310-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
49
|
+
.. |310-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.10.svg
|
|
50
50
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
51
51
|
|
|
52
|
-
.. |311-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
52
|
+
.. |311-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.11.svg
|
|
53
53
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
54
54
|
|
|
55
|
-
.. |312-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
55
|
+
.. |312-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.12.svg
|
|
56
56
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
57
57
|
|
|
58
|
-
.. |313-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/
|
|
58
|
+
.. |313-windows| image:: https://raw.githubusercontent.com/PyMoDAQ/PyMoDAQ/badges/pymodaq_data/state-machine-simplify/tests_Windows_3.13.svg
|
|
59
59
|
:target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/tests-data.yml
|
|
60
60
|
|
|
61
61
|
|
|
@@ -86,7 +86,9 @@ def dimensionless_aware_reduce_units(q: Type[Q_]) -> Type[Q_]:
|
|
|
86
86
|
-------
|
|
87
87
|
The reduced quantity
|
|
88
88
|
"""
|
|
89
|
-
|
|
89
|
+
# this may fire a pint.errors.UndefinedBehavior warning when the magnitude is a numpy array
|
|
90
|
+
# but pint https://github.com/hgrecco/pint/issues/2274 fixed this in July 2026
|
|
91
|
+
# at the moment, it just returns the same quantity layout
|
|
90
92
|
return q.to_compact() if q.dimensionless else q.to_reduced_units()
|
|
91
93
|
|
|
92
94
|
def check_units(units: str):
|
|
@@ -529,6 +531,16 @@ class Axis(SerializableBase):
|
|
|
529
531
|
if self._data is None:
|
|
530
532
|
self._size = _size
|
|
531
533
|
|
|
534
|
+
@property
|
|
535
|
+
def axis_width(self) -> Q_:
|
|
536
|
+
"""get the width of the axis in axis unit
|
|
537
|
+
|
|
538
|
+
That is the difference between the max value and the min value of the axis
|
|
539
|
+
"""
|
|
540
|
+
if self.scaling is not None:
|
|
541
|
+
return Q_(self.size * self.scaling, self.units)
|
|
542
|
+
else:
|
|
543
|
+
return Q_(self.get_data().max() - self.get_data().min(), self.units)
|
|
532
544
|
@staticmethod
|
|
533
545
|
def _check_index_valid(index: int):
|
|
534
546
|
if not isinstance(index, int):
|
|
@@ -653,10 +665,10 @@ class Axis(SerializableBase):
|
|
|
653
665
|
"""find the index of the threshold value within the axis"""
|
|
654
666
|
if isinstance(threshold, Q_):
|
|
655
667
|
threshold = threshold.m_as(self.units)
|
|
656
|
-
if threshold
|
|
668
|
+
if threshold <= self.min():
|
|
657
669
|
return 0
|
|
658
|
-
elif threshold
|
|
659
|
-
return len(self)
|
|
670
|
+
elif threshold >= self.max():
|
|
671
|
+
return len(self)
|
|
660
672
|
elif self._data is not None:
|
|
661
673
|
return mutils.find_index(self._data, threshold)[0][0]
|
|
662
674
|
else:
|
|
@@ -702,7 +714,7 @@ class DataLowLevel:
|
|
|
702
714
|
|
|
703
715
|
@name.setter
|
|
704
716
|
def name(self, other_name: str):
|
|
705
|
-
self._name = other_name
|
|
717
|
+
self._name = str(other_name)
|
|
706
718
|
|
|
707
719
|
@property
|
|
708
720
|
def timestamp(self):
|
|
@@ -2141,6 +2153,10 @@ class DataWithAxes(DataBase, SerializableBase):
|
|
|
2141
2153
|
dwa.timestamp = timestamp
|
|
2142
2154
|
return dwa, remaining_bytes
|
|
2143
2155
|
|
|
2156
|
+
def get_axes_sizes(self) -> Iterable[Q_]:
|
|
2157
|
+
self.create_missing_axes()
|
|
2158
|
+
return [self.get_axis_from_index(index)[0].axis_width for index in range(len(self.axes))]
|
|
2159
|
+
|
|
2144
2160
|
def check_axes_linear(self, axes: List[Axis] = None) -> bool:
|
|
2145
2161
|
""" Check if any axis may be non linear
|
|
2146
2162
|
|
|
@@ -3747,9 +3763,16 @@ class DataToExport(DataLowLevel, SerializableBase):
|
|
|
3747
3763
|
data, _ = find_objects_in_list_from_attr_name_val(self.data, 'name', name, return_first=True)
|
|
3748
3764
|
return data
|
|
3749
3765
|
|
|
3750
|
-
def get_data_from_names(self, names: List[str]) -> DataToExport:
|
|
3766
|
+
def get_data_from_names(self, names: List[str] | str) -> DataToExport:
|
|
3767
|
+
if isinstance(names, str):
|
|
3768
|
+
names = [names]
|
|
3751
3769
|
return DataToExport(self.name, data=[dwa for dwa in self if dwa.name in names])
|
|
3752
3770
|
|
|
3771
|
+
def get_data_from_origins(self, origins: list[str] | str) -> DataToExport:
|
|
3772
|
+
if isinstance(origins, str):
|
|
3773
|
+
origins = [origins]
|
|
3774
|
+
return DataToExport(self.name, data=[dwa for dwa in self if dwa.origin in origins])
|
|
3775
|
+
|
|
3753
3776
|
def get_data_from_name_origin(self, name: str, origin: str = '') -> DataWithAxes:
|
|
3754
3777
|
"""Get the data matching the given name and the given origin"""
|
|
3755
3778
|
if origin == '':
|
|
@@ -3771,9 +3794,8 @@ class DataToExport(DataLowLevel, SerializableBase):
|
|
|
3771
3794
|
return ind
|
|
3772
3795
|
raise ValueError
|
|
3773
3796
|
|
|
3774
|
-
def index_from_name_origin(self, name: str, origin: str = '') ->
|
|
3797
|
+
def index_from_name_origin(self, name: str, origin: str = '') -> int:
|
|
3775
3798
|
"""Get the index of a given DataWithAxes within the list of data"""
|
|
3776
|
-
"""Get the data matching the given name and the given origin"""
|
|
3777
3799
|
if origin == '':
|
|
3778
3800
|
_, index = find_objects_in_list_from_attr_name_val(self.data, 'name', name, return_first=True)
|
|
3779
3801
|
else:
|
|
@@ -242,7 +242,7 @@ class Node(object):
|
|
|
242
242
|
return self.attrs['TITLE']
|
|
243
243
|
|
|
244
244
|
@property
|
|
245
|
-
def path(self):
|
|
245
|
+
def path(self) -> str:
|
|
246
246
|
"""return node path
|
|
247
247
|
Parameters
|
|
248
248
|
----------
|
|
@@ -575,6 +575,11 @@ class H5Backend:
|
|
|
575
575
|
self._swmr_enabled = False
|
|
576
576
|
self.set_backend(backend)
|
|
577
577
|
|
|
578
|
+
@property
|
|
579
|
+
def swmr_mode(self) -> bool:
|
|
580
|
+
return self._swmr_mode
|
|
581
|
+
|
|
582
|
+
|
|
578
583
|
def set_backend(self, backend: str):
|
|
579
584
|
"""Switch the active backend, closing any open file first.
|
|
580
585
|
|
|
@@ -977,7 +982,7 @@ class H5Backend:
|
|
|
977
982
|
else:
|
|
978
983
|
return self.get_node(node.parent)
|
|
979
984
|
|
|
980
|
-
def get_children(self, where):
|
|
985
|
+
def get_children(self, where) -> dict[str, Node]:
|
|
981
986
|
"""Get a dict containing all children node hanging from where with their name as keys and types among Node,
|
|
982
987
|
CARRAY, EARRAY, VLARRAY or StringARRAY
|
|
983
988
|
|
|
@@ -1023,12 +1028,45 @@ class H5Backend:
|
|
|
1023
1028
|
children[child_name] = _cls(child, self.backend)
|
|
1024
1029
|
return children
|
|
1025
1030
|
|
|
1026
|
-
def walk_nodes(self, where):
|
|
1031
|
+
def walk_nodes(self, where: str| Node, depth: int = None, only_groups=False):
|
|
1032
|
+
""" Node Generator recursively iterating in the tree starting from where down to the specified depth
|
|
1033
|
+
(counted from where).
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
Parameters
|
|
1037
|
+
----------
|
|
1038
|
+
where: str | Node
|
|
1039
|
+
The starting node of the iteration
|
|
1040
|
+
depth: int
|
|
1041
|
+
The depth of the iteration in the h5 tree
|
|
1042
|
+
only_groups: bool
|
|
1043
|
+
if False (default) return all nodes otherwise retruns only GROUP instances
|
|
1044
|
+
|
|
1045
|
+
Yields
|
|
1046
|
+
------
|
|
1047
|
+
Node
|
|
1048
|
+
"""
|
|
1027
1049
|
where = self.get_node(where) # return a node object in case where is a string
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1050
|
+
if only_groups and where.attrs['CLASS'] != 'GROUP':
|
|
1051
|
+
pass
|
|
1052
|
+
else:
|
|
1053
|
+
yield where
|
|
1054
|
+
|
|
1055
|
+
if depth == 0:
|
|
1056
|
+
return
|
|
1057
|
+
else:
|
|
1058
|
+
for gr in self.walk_groups(where):
|
|
1059
|
+
for child in self.get_children(gr).values():
|
|
1060
|
+
node_path = child.path[len(where.path):]
|
|
1061
|
+
if node_path[0] == '/':
|
|
1062
|
+
node_path = node_path[1:]
|
|
1063
|
+
if depth is not None and node_path.count('/') == depth:
|
|
1064
|
+
return
|
|
1065
|
+
else:
|
|
1066
|
+
if only_groups and child.attrs['CLASS'] != 'GROUP':
|
|
1067
|
+
pass
|
|
1068
|
+
else:
|
|
1069
|
+
yield child
|
|
1032
1070
|
|
|
1033
1071
|
def walk_groups(self, where):
|
|
1034
1072
|
where = self.get_node(where) # return a node object in case where is a string
|
|
@@ -297,12 +297,17 @@ class DataSaverLoader(DataManagement):
|
|
|
297
297
|
data_type = DataType['data']
|
|
298
298
|
|
|
299
299
|
def __init__(self, h5saver: Union[H5SaverLowLevel, Path],
|
|
300
|
-
new_file: bool = False,
|
|
300
|
+
new_file: bool = False,
|
|
301
|
+
metadata: dict = None,
|
|
302
|
+
save_type=SaveType.custom,
|
|
303
|
+
swmr_mode=False):
|
|
301
304
|
self.data_type = enum_checker(DataType, self.data_type)
|
|
302
305
|
|
|
303
306
|
if isinstance(h5saver, (Path, str)):
|
|
304
307
|
h5saver = H5SaverLowLevel.from_file(h5saver, save_type,
|
|
305
|
-
new_file=new_file,
|
|
308
|
+
new_file=new_file,
|
|
309
|
+
metadata=metadata,
|
|
310
|
+
swmr_mode=swmr_mode)
|
|
306
311
|
|
|
307
312
|
self._h5saver = h5saver
|
|
308
313
|
self._axis_saver = AxisSaverLoader(self._h5saver)
|
|
@@ -708,7 +713,7 @@ class DataExtendedSaver(DataSaverLoader):
|
|
|
708
713
|
Parameters
|
|
709
714
|
----------
|
|
710
715
|
h5saver: H5SaverLowLevel
|
|
711
|
-
extended_shape:
|
|
716
|
+
extended_shape: Iterable[int]
|
|
712
717
|
the extra shape compared to the data the h5array will have
|
|
713
718
|
|
|
714
719
|
Attributes
|
|
@@ -718,7 +723,9 @@ class DataExtendedSaver(DataSaverLoader):
|
|
|
718
723
|
"""
|
|
719
724
|
data_type = DataType['data']
|
|
720
725
|
|
|
721
|
-
def __init__(self, h5saver: H5SaverLowLevel,
|
|
726
|
+
def __init__(self, h5saver: H5SaverLowLevel,
|
|
727
|
+
extended_shape: Iterable[int],
|
|
728
|
+
fill_value=None):
|
|
722
729
|
super().__init__(h5saver)
|
|
723
730
|
self.extended_shape = extended_shape
|
|
724
731
|
self.fill_value = fill_value
|
|
@@ -784,7 +791,9 @@ class DataExtendedSaver(DataSaverLoader):
|
|
|
784
791
|
# because there will be len(self.extended_shape) extra navigation axes
|
|
785
792
|
self._axis_saver.add_axis(where, axis)
|
|
786
793
|
|
|
787
|
-
def add_data(self, where: Union[Node, str],
|
|
794
|
+
def add_data(self, where: Union[Node, str],
|
|
795
|
+
data: DataWithAxes,
|
|
796
|
+
indexes: Iterable[int],
|
|
788
797
|
distribution=DataDistribution['uniform']):
|
|
789
798
|
"""Adds given DataWithAxes at a location within the initialized h5 array
|
|
790
799
|
|
|
@@ -1035,7 +1044,10 @@ class DataToExportExtendedSaver(DataToExportSaver):
|
|
|
1035
1044
|
the extra shape compared to the data the h5array will have
|
|
1036
1045
|
"""
|
|
1037
1046
|
|
|
1038
|
-
def __init__(self,
|
|
1047
|
+
def __init__(self,
|
|
1048
|
+
h5saver: H5SaverLowLevel,
|
|
1049
|
+
extended_shape: Iterable[int],
|
|
1050
|
+
fill_value=None):
|
|
1039
1051
|
super().__init__(h5saver)
|
|
1040
1052
|
self._data_saver = DataExtendedSaver(h5saver, extended_shape, fill_value=fill_value)
|
|
1041
1053
|
self._nav_axis_saver = AxisSaverLoader(h5saver)
|
|
@@ -1054,7 +1066,9 @@ class DataToExportExtendedSaver(DataToExportSaver):
|
|
|
1054
1066
|
for axis in axes:
|
|
1055
1067
|
self._nav_axis_saver.add_axis(nav_group, axis)
|
|
1056
1068
|
|
|
1057
|
-
def add_data(self, where: Union[Node, str],
|
|
1069
|
+
def add_data(self, where: Union[Node, str],
|
|
1070
|
+
data: DataToExport,
|
|
1071
|
+
indexes: Iterable[int],
|
|
1058
1072
|
distribution=DataDistribution.uniform,
|
|
1059
1073
|
settings_as_xml='', **kwargs):
|
|
1060
1074
|
|
|
@@ -1095,7 +1109,7 @@ class DataToExportExtendedSaver(DataToExportSaver):
|
|
|
1095
1109
|
|
|
1096
1110
|
|
|
1097
1111
|
class DataLoader:
|
|
1098
|
-
"""Specialized Object to load DataWithAxes
|
|
1112
|
+
"""Specialized Object to load DataWithAxes / DataToExport objects from a h5file
|
|
1099
1113
|
|
|
1100
1114
|
On the contrary to DataSaverLoader, does include navigation axes stored elsewhere in the h5file
|
|
1101
1115
|
(for instance if saved from the DAQ_Scan)
|
|
@@ -1105,12 +1119,15 @@ class DataLoader:
|
|
|
1105
1119
|
h5saver: H5SaverLowLevel or Path
|
|
1106
1120
|
"""
|
|
1107
1121
|
|
|
1108
|
-
def __init__(self, h5saver: Union[H5SaverLowLevel, Path]
|
|
1122
|
+
def __init__(self, h5saver: Union[H5SaverLowLevel, Path],
|
|
1123
|
+
swmr_mode = False):
|
|
1109
1124
|
self._axis_loader: AxisSaverLoader = None
|
|
1110
1125
|
self._data_loader: DataSaverLoader = None
|
|
1111
1126
|
|
|
1112
1127
|
if isinstance(h5saver, (Path, str)):
|
|
1113
|
-
h5saver = H5SaverLowLevel.from_file(h5saver
|
|
1128
|
+
h5saver = H5SaverLowLevel.from_file(h5saver,
|
|
1129
|
+
swmr_mode=swmr_mode,
|
|
1130
|
+
mode='r')
|
|
1114
1131
|
|
|
1115
1132
|
self.h5saver = h5saver
|
|
1116
1133
|
|
|
@@ -1129,8 +1146,8 @@ class DataLoader:
|
|
|
1129
1146
|
|
|
1130
1147
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
1131
1148
|
self.close_file()
|
|
1132
|
-
@property
|
|
1133
1149
|
|
|
1150
|
+
@property
|
|
1134
1151
|
def raw_group(self) -> Node:
|
|
1135
1152
|
""" Get the base RawGroup where raw data should be saved
|
|
1136
1153
|
|
|
@@ -1141,9 +1158,11 @@ class DataLoader:
|
|
|
1141
1158
|
def close_file(self):
|
|
1142
1159
|
self._h5saver.close_file()
|
|
1143
1160
|
|
|
1144
|
-
def walk_nodes(self, where: Union[str, Node] = '/'
|
|
1161
|
+
def walk_nodes(self, where: Union[str, Node] = '/', depth: int = None,
|
|
1162
|
+
only_groups=False) -> Iterable[Node]:
|
|
1145
1163
|
"""Return a Node generator iterating over the h5file content"""
|
|
1146
|
-
return self.h5saver.walk_nodes(where
|
|
1164
|
+
return self.h5saver.walk_nodes(where, depth=depth,
|
|
1165
|
+
only_groups=only_groups)
|
|
1147
1166
|
|
|
1148
1167
|
def get_node(self, where: Union[Node, str], name: str = None) -> Node:
|
|
1149
1168
|
""" Convenience method to get node"""
|
|
@@ -1198,17 +1217,25 @@ class DataLoader:
|
|
|
1198
1217
|
if nav_group is not None:
|
|
1199
1218
|
nav_axes = self._axis_loader.get_axes(nav_group)
|
|
1200
1219
|
axes = data.axes[:]
|
|
1220
|
+
# in swmr mode, if at the time where the axis is read, a writer added stuff
|
|
1221
|
+
# then the axis and the data may not be consistent. Below is an attempt to correct this
|
|
1222
|
+
for ind_nav, nav_axe in enumerate(nav_axes):
|
|
1223
|
+
if nav_axe.size > data.shape[data.nav_indexes[ind_nav]]:
|
|
1224
|
+
nav_axe.data = nav_axe.get_data()[:data.shape[data.nav_indexes[ind_nav]]]
|
|
1201
1225
|
axes.extend(nav_axes)
|
|
1202
1226
|
data.axes = axes
|
|
1203
1227
|
data.get_dim_from_data_axes()
|
|
1204
1228
|
data.create_missing_axes()
|
|
1205
1229
|
return data
|
|
1206
1230
|
|
|
1207
|
-
def load_all(self, where: GROUP, data: DataToExport = None, with_bkg=False) -> DataToExport:
|
|
1231
|
+
def load_all(self, where: GROUP | str, data: DataToExport = None, with_bkg=False) -> DataToExport:
|
|
1208
1232
|
if data is None:
|
|
1209
1233
|
data = DataToExport('Loaded data')
|
|
1210
1234
|
where = self._h5saver.get_node(where)
|
|
1211
|
-
|
|
1235
|
+
try:
|
|
1236
|
+
children_dict = where.children()
|
|
1237
|
+
except AttributeError:
|
|
1238
|
+
children_dict = {where.name: where}
|
|
1212
1239
|
data_list = []
|
|
1213
1240
|
for child in children_dict:
|
|
1214
1241
|
if isinstance(children_dict[child], GROUP):
|
|
@@ -92,7 +92,9 @@ class H5SaverLowLevel(H5Backend):
|
|
|
92
92
|
|
|
93
93
|
@classmethod
|
|
94
94
|
def from_file(cls, path: Union[Path, str], save_type: SaveType = 'scan',
|
|
95
|
-
new_file: bool = False, metadata: dict = None
|
|
95
|
+
new_file: bool = False, metadata: dict = None,
|
|
96
|
+
swmr_mode: bool = False,
|
|
97
|
+
mode='a') -> 'H5SaverLowLevel':
|
|
96
98
|
"""Create and initialise an H5SaverLowLevel from a file path.
|
|
97
99
|
|
|
98
100
|
Convenience factory that combines the constructor and :meth:`init_file`
|
|
@@ -108,6 +110,11 @@ class H5SaverLowLevel(H5Backend):
|
|
|
108
110
|
opened for appending.
|
|
109
111
|
metadata: dict or None
|
|
110
112
|
Extra attributes written to the raw-data group on creation.
|
|
113
|
+
swmr_mode: bool
|
|
114
|
+
If True, prepare the file for SWMR (h5py backend only)
|
|
115
|
+
mode: str
|
|
116
|
+
valid if new_file is False. Then could be 'r' for readonly or 'a' to append data
|
|
117
|
+
|
|
111
118
|
|
|
112
119
|
Returns
|
|
113
120
|
-------
|
|
@@ -115,7 +122,11 @@ class H5SaverLowLevel(H5Backend):
|
|
|
115
122
|
A fully initialised instance ready for reading/writing.
|
|
116
123
|
"""
|
|
117
124
|
h5saver = cls(save_type)
|
|
118
|
-
h5saver.init_file(file_name=Path(path),
|
|
125
|
+
h5saver.init_file(file_name=Path(path),
|
|
126
|
+
new_file=new_file,
|
|
127
|
+
metadata=metadata,
|
|
128
|
+
swmr_mode=swmr_mode,
|
|
129
|
+
mode=mode)
|
|
119
130
|
return h5saver
|
|
120
131
|
|
|
121
132
|
def set_swmr_flush_interval(self, interval: int):
|
|
@@ -149,8 +160,11 @@ class H5SaverLowLevel(H5Backend):
|
|
|
149
160
|
def h5_file(self):
|
|
150
161
|
return self._h5file
|
|
151
162
|
|
|
152
|
-
def init_file(self, file_name: Path, raw_group_name='RawData',
|
|
153
|
-
|
|
163
|
+
def init_file(self, file_name: Path, raw_group_name='RawData',
|
|
164
|
+
new_file=False,
|
|
165
|
+
metadata: dict = None,
|
|
166
|
+
swmr_mode: bool = False,
|
|
167
|
+
mode: str = 'a'):
|
|
154
168
|
"""Initializes a new h5 file,
|
|
155
169
|
|
|
156
170
|
Should have an extension with h5 in it.
|
|
@@ -167,6 +181,8 @@ class H5SaverLowLevel(H5Backend):
|
|
|
167
181
|
A dictionary to be saved as attributes
|
|
168
182
|
swmr_mode: bool
|
|
169
183
|
If True, prepare the file for SWMR (h5py backend only)
|
|
184
|
+
mode: str
|
|
185
|
+
valid if new_file is False. Then could be 'r' for readonly or 'a' to append data
|
|
170
186
|
|
|
171
187
|
Returns
|
|
172
188
|
-------
|
|
@@ -200,7 +216,7 @@ class H5SaverLowLevel(H5Backend):
|
|
|
200
216
|
return
|
|
201
217
|
|
|
202
218
|
self.close_file()
|
|
203
|
-
self.open_file(self.h5_file_path.joinpath(self.h5_file_name), 'w' if new_file else
|
|
219
|
+
self.open_file(self.h5_file_path.joinpath(self.h5_file_name), 'w' if new_file else mode,
|
|
204
220
|
title='PyMoDAQ file', swmr_mode=swmr_mode)
|
|
205
221
|
|
|
206
222
|
self._raw_group = self.get_set_group(self.root(), raw_group_name, title='Data from PyMoDAQ modules')
|
|
@@ -20,7 +20,10 @@ logger = set_logger(get_module_name(__file__))
|
|
|
20
20
|
config = configmod.GlobalConfig()
|
|
21
21
|
|
|
22
22
|
PLOT_COLORS = PlotColors()
|
|
23
|
-
|
|
23
|
+
try:
|
|
24
|
+
PLOT_COLORS.remove((255, 255, 255))# remove white color as plotted on white background
|
|
25
|
+
except ValueError:
|
|
26
|
+
pass # this color is not in PLOT_COLORS (maybe because light style is used)
|
|
24
27
|
PLOT_COLORS = PlotColors([(np.array(color) / 255).tolist() for color in PLOT_COLORS]) # translation to matplotlib
|
|
25
28
|
|
|
26
29
|
|
|
@@ -38,18 +41,26 @@ class Plotter(PlotterBase):
|
|
|
38
41
|
def plot(self, data: Union[DataWithAxes, DataToExport], *args, viewer=None,
|
|
39
42
|
**kwargs) -> plt.Figure:
|
|
40
43
|
fig = plt.figure()
|
|
44
|
+
if 'linewidth' in kwargs:
|
|
45
|
+
linewidth = kwargs['linewidth']
|
|
46
|
+
else:
|
|
47
|
+
linewidth = self.linewidth
|
|
41
48
|
|
|
42
49
|
if isinstance(data, DataWithAxes):
|
|
43
50
|
self.n_columns = len(data) if data.dim.name == 'Data2D' else 1
|
|
44
|
-
self.plot_dwa(data, *args, **kwargs)
|
|
51
|
+
self.plot_dwa(data, *args, linewidth=linewidth, **kwargs)
|
|
45
52
|
elif isinstance(data, DataToExport):
|
|
46
53
|
self.n_columns = max([len(dwa) if dwa.dim.name == 'Data2D' else 1 for dwa in data])
|
|
47
54
|
self.n_lines = len(data)
|
|
48
|
-
self.plot_dte(data, *args, **kwargs)
|
|
55
|
+
self.plot_dte(data, *args, linewidth=linewidth, **kwargs)
|
|
49
56
|
plt.tight_layout()
|
|
50
57
|
fig.suptitle(f'{data.name} taken the {datetime.datetime.fromtimestamp(data.timestamp)}')
|
|
51
58
|
return fig
|
|
52
59
|
|
|
60
|
+
@property
|
|
61
|
+
def linewidth(self) -> int:
|
|
62
|
+
return config('data', 'plotting', 'linewidth')
|
|
63
|
+
|
|
53
64
|
def plot_dwa(self, dwa: DataWithAxes, *args, **kwargs):
|
|
54
65
|
if dwa.dim.name == 'Data1D':
|
|
55
66
|
if len(dwa.axes) == 0:
|
{pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/resources/config_template.toml
RENAMED
|
@@ -26,3 +26,4 @@ backend = ['h5py', 'tables', 'h5pyd'] # first element is the default, mostly te
|
|
|
26
26
|
backend = ['matplotlib'] # either 'matplotlib' or 'qt' or any other custom backend
|
|
27
27
|
plot_colors = [[255, 255, 255], [255, 0, 0], [0, 255, 0], [0, 0, 255], [14, 207, 189], [207, 14, 166], [207, 204, 14]]
|
|
28
28
|
process_roi = true # if True subdata is extracted from the ROI in the data viewers
|
|
29
|
+
linewidth = 1 # default linewidth of the plots
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/exporters/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/h5modules/exporters/hyperspy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/plotting/plotter/plotters/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pymodaq_data-5.2.10 → pymodaq_data-5.3.0a0}/src/pymodaq_data/post_treatment/process_to_scalar.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|