pymodaq_data 0.0.1__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.
@@ -0,0 +1,133 @@
1
+ from typing import List, Tuple, Any, TYPE_CHECKING, Union
2
+ import sys
3
+ import datetime
4
+
5
+ import numpy as np
6
+
7
+ from pymodaq_utils.logger import set_logger, get_module_name
8
+ from pymodaq_utils import config as configmod
9
+ from pymodaq_data.data import DataDim, DataWithAxes, DataToExport
10
+ from pymodaq_utils import utils
11
+ from pymodaq_data.plotting.plotter.plotter import PlotterBase, PlotterFactory
12
+
13
+ from matplotlib import pyplot as plt
14
+
15
+ if TYPE_CHECKING:
16
+ pass
17
+
18
+ logger = set_logger(get_module_name(__file__))
19
+ config = configmod.Config()
20
+
21
+ PLOT_COLORS = utils.plot_colors.copy()
22
+ PLOT_COLORS.remove((255, 255, 255)) # remove white color as plotted on white background
23
+ PLOT_COLORS = [(np.array(color) / 255).tolist() for color in PLOT_COLORS] # translation to matplotlib
24
+
25
+
26
+ @PlotterFactory.register()
27
+ class Plotter(PlotterBase):
28
+ backend = 'matplotlib'
29
+
30
+ def __init__(self, **_ignored):
31
+ super().__init__()
32
+ self.n_lines = 1
33
+ self.n_columns = 1
34
+ self.ind_line = 0
35
+ self.ind_column = 0
36
+
37
+ def plot(self, data: Union[DataWithAxes, DataToExport], *args, viewer=None,
38
+ **kwargs) -> plt.Figure:
39
+ fig = plt.figure()
40
+
41
+ if isinstance(data, DataWithAxes):
42
+ self.n_columns = len(data) if data.dim.name == 'Data2D' else 1
43
+ self.plot_dwa(data, *args, **kwargs)
44
+ elif isinstance(data, DataToExport):
45
+ self.n_columns = max([len(dwa) if dwa.dim.name == 'Data2D' else 1 for dwa in data])
46
+ self.n_lines = len(data)
47
+ self.plot_dte(data, *args, **kwargs)
48
+ plt.tight_layout()
49
+ fig.suptitle(f'{data.name} taken the {datetime.datetime.fromtimestamp(data.timestamp)}')
50
+ return fig
51
+
52
+ def plot_dwa(self, dwa: DataWithAxes, *args, **kwargs):
53
+ if dwa.dim.name == 'Data1D':
54
+ if len(dwa.axes) == 0:
55
+ dwa.create_missing_axes()
56
+ self.ind_column = 0
57
+ self.plot1D(dwa, *args, **kwargs)
58
+ elif dwa.dim.name == 'Data2D':
59
+ if len(dwa.axes) < 2:
60
+ dwa.create_missing_axes()
61
+ self.plot2D(dwa, *args, **kwargs)
62
+
63
+ def plot_dte(self, dte: DataToExport, *args, **kwargs):
64
+ for ind in range(len(dte)):
65
+ self.ind_line = ind
66
+ self.plot_dwa(dte[ind], *args, **kwargs)
67
+
68
+ def plot1D(self, dwa: DataWithAxes, *args, **kwargs):
69
+ plt.subplot(self.n_lines, self.n_columns,
70
+ (self.n_columns * self.ind_line) + 1)
71
+ for ind_data, data_array in enumerate(dwa):
72
+ plt.plot(dwa.axes[0].get_data(), data_array, *args, color=PLOT_COLORS[ind_data],
73
+ **kwargs)
74
+ if dwa.errors is not None:
75
+ plt.fill_between(dwa.axes[0].get_data(), data_array - dwa.get_error(ind_data),
76
+ data_array + dwa.get_error(ind_data), *args,
77
+ color=PLOT_COLORS[ind_data] + [0.3], **kwargs)
78
+ plt.legend(dwa.labels)
79
+ #plt.title(f'{dwa.name}')
80
+ plt.xlabel(f'{dwa.axes[0].label} ({dwa.axes[0].units})')
81
+ plt.ylabel(dwa.name)
82
+
83
+ def plot2D(self, dwa: DataWithAxes, *args, **kwargs):
84
+ xaxis = dwa.get_axis_from_index(1)[0]
85
+ yaxis = dwa.get_axis_from_index(0)[0]
86
+
87
+ x = xaxis.get_data()
88
+ y = yaxis.get_data()
89
+ for ind_plot, dwa_array in enumerate(dwa):
90
+ self.ind_column = ind_plot
91
+ plt.subplot(self.n_lines, self.n_columns,
92
+ (self.n_columns * self.ind_line) + ind_plot + 1)
93
+ X, Y = np.meshgrid(x, y)
94
+ plt.pcolormesh(X, Y, dwa_array, *args, **kwargs)
95
+ plt.title(f'{dwa.name}/{dwa.labels[ind_plot]}')
96
+ plt.xlabel(f'{xaxis.label} ({xaxis.units})')
97
+ plt.ylabel(f'{yaxis.label} ({yaxis.units})')
98
+
99
+
100
+ # if __name__ == '__main__':
101
+ # from pymodaq.utils import data as data_mod
102
+ # import numpy as np
103
+ # from pymodaq.utils.math_utils import gauss1D, gauss2D
104
+ # from pymodaq.utils.plotting.plotter.plotter import PlotterFactory
105
+ # plotter_factory = PlotterFactory()
106
+ #
107
+ # x = np.linspace(0, 100, 101)
108
+ # y = np.linspace(0, 100, 101)
109
+ # y1 = gauss2D(x, 50, 20, y, 40, 7)
110
+ #
111
+ #
112
+ # QtWidgets.QApplication.processEvents()
113
+ # dwa = data_mod.DataRaw('mydata', data=[y1, y1, y1],
114
+ # axes=[data_mod.Axis('xaxis', 'x units', data=x, index=0,
115
+ # spread_order=0),
116
+ # data_mod.Axis('yaxis', 'y units', data=y, index=1,
117
+ # spread_order=0)
118
+ # ],
119
+ # labels=['MAG', 'PHASE'],
120
+ # nav_indexes=())
121
+ # dte = dwa.as_dte('mydte')
122
+ # dwa_mean = dwa.mean()
123
+ # dwa_mean.name = 'mean'
124
+ # dwa_mean_2 = dwa.mean(1)
125
+ # dwa_mean_2.name = 'mean2'
126
+ # dte.append(dwa_mean)
127
+ # dte.append(dwa_mean_2)
128
+ #
129
+ # fig = dwa.plot('matplotlib')
130
+ # fig.savefig('myplot.png')
131
+ #
132
+ # fig2 = dte.plot('matplotlib')
133
+ # fig2.savefig('mydte.png')
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created the 27/10/2022
4
+
5
+ @author: Sebastien Weber
6
+ """
@@ -0,0 +1,234 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created the 04/11/2022
4
+
5
+ @author: Sebastien Weber
6
+ """
7
+ import numpy as np
8
+ from numbers import Number
9
+ from typing import List, Tuple
10
+ from abc import ABCMeta, abstractmethod, abstractproperty
11
+
12
+ from pymodaq_utils.factory import ObjectFactory
13
+ from pymodaq_utils import math_utils as mutils
14
+ from pymodaq_data.data import DataWithAxes, Axis, DataRaw, DataBase, DataDim, DataCalculated
15
+
16
+
17
+ config_processors = {
18
+ }
19
+
20
+
21
+ class DataProcessorBase(metaclass=ABCMeta):
22
+ """Apply processing functions to signal data. This function should return a DataWithAxes.
23
+
24
+ Attributes
25
+ ----------
26
+ apply_to: DataDim
27
+ Specify on which type of data dimensionality this processor can be applied to, if only 1D:
28
+ apply_to = DataDim['Data1D']
29
+
30
+ """
31
+
32
+ apply_to: DataDim = abstractproperty
33
+
34
+ def process(self, data: DataWithAxes) -> DataWithAxes:
35
+ return self.operate(data)
36
+
37
+ @abstractmethod
38
+ def operate(self, sub_data: DataWithAxes):
39
+ pass
40
+
41
+ @staticmethod
42
+ def flatten_signal_dim(sub_data: DataWithAxes) -> Tuple[Tuple, np.ndarray]:
43
+ """flattens data's ndarrays along the signal dimensions"""
44
+ data_arrays = []
45
+ new_shape = [sub_data.shape[ind] for ind in sub_data.nav_indexes]
46
+ new_shape.append(np.prod([sub_data.shape[ind] for ind in sub_data.sig_indexes]))
47
+
48
+ # for each data in subdata, apply the function, here argmax, along the flattened dimension. Then unravel the
49
+ # possible multiple indexes (1 for 1D, 2 for 2D)
50
+ for ind, data in enumerate(sub_data):
51
+ data_arrays.append(data.reshape(new_shape))
52
+ return new_shape, data_arrays
53
+
54
+ def __call__(self, **kwargs):
55
+ return self(**kwargs)
56
+
57
+
58
+ class DataProcessorFactory(ObjectFactory):
59
+ def get(self, processor_name, **kwargs) -> DataProcessorBase:
60
+ return self.create(processor_name, **kwargs)
61
+
62
+ @property
63
+ def functions(self):
64
+ """Get the list of processor functions"""
65
+ return self.keys_function(do_sort=False)
66
+
67
+ def functions_filtered(self, dim: DataDim):
68
+ """Get the list of processor functions that could be applied to data having a given dimensionality"""
69
+ return [key for key in self.functions if self.get(key).apply_to >= dim]
70
+
71
+
72
+ @DataProcessorFactory.register('mean')
73
+ class MeanProcessor(DataProcessorBase):
74
+ apply_to = DataDim['DataND']
75
+
76
+ def operate(self, sub_data: DataWithAxes):
77
+ data_arrays = [np.atleast_1d(np.mean(data, axis=sub_data.sig_indexes)) for data in sub_data]
78
+ return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
79
+
80
+
81
+ @DataProcessorFactory.register('std')
82
+ class StdProcessor(DataProcessorBase):
83
+ apply_to = DataDim['DataND']
84
+
85
+ def operate(self, sub_data: DataWithAxes):
86
+ data_arrays = [np.atleast_1d(np.std(data, axis=sub_data.sig_indexes)) for data in sub_data]
87
+ return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
88
+
89
+
90
+ @DataProcessorFactory.register('sum')
91
+ class SumProcessor(DataProcessorBase):
92
+ apply_to = DataDim['DataND']
93
+
94
+ def operate(self, sub_data: DataWithAxes):
95
+ data_arrays = [np.atleast_1d(np.sum(data, axis=sub_data.sig_indexes)) for data in sub_data]
96
+ return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
97
+
98
+
99
+ @DataProcessorFactory.register('max')
100
+ class MaxProcessor(DataProcessorBase):
101
+ apply_to = DataDim['DataND']
102
+
103
+ def operate(self, sub_data: DataWithAxes):
104
+ data_arrays = [np.atleast_1d(np.max(data, axis=sub_data.sig_indexes)) for data in sub_data]
105
+ return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
106
+
107
+
108
+ @DataProcessorFactory.register('min')
109
+ class MinProcessor(DataProcessorBase):
110
+ apply_to = DataDim['DataND']
111
+
112
+ def operate(self, sub_data: DataWithAxes):
113
+ data_arrays = [np.atleast_1d(np.min(data, axis=sub_data.sig_indexes)) for data in sub_data]
114
+ return sub_data.deepcopy_with_new_data(data_arrays, sub_data.sig_indexes)
115
+
116
+
117
+ @DataProcessorFactory.register('argmax')
118
+ class ArgMaxProcessor(DataProcessorBase):
119
+ apply_to = DataDim['DataND']
120
+
121
+ def operate(self, sub_data: DataWithAxes):
122
+ """Extract info from sub-DataWithAxes
123
+
124
+ Retrieve the signal axis values of the maximum position of the data
125
+
126
+ Notes
127
+ -----
128
+ For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
129
+ (compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
130
+ the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
131
+ a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
132
+ dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
133
+ """
134
+ new_data_arrays = []
135
+ new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
136
+
137
+ for dat in flattened_arrays:
138
+ indexes = np.unravel_index(np.nanargmax(dat, len(new_shape)-1), sub_data.shape)[len(sub_data.nav_indexes):]
139
+ # from the unraveled index, retrieve the corresponding axis value
140
+ for ind in range(len(indexes)):
141
+ axis_data = sub_data.get_axis_from_index(sub_data.sig_indexes[ind])[0].get_data()
142
+ new_data_arrays.append(np.atleast_1d(axis_data[indexes[ind]]))
143
+ return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
144
+ axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes],
145
+ distribution=sub_data.distribution)
146
+
147
+
148
+ @DataProcessorFactory.register('argmin')
149
+ class ArgMinProcessor(DataProcessorBase):
150
+ apply_to = DataDim['DataND']
151
+
152
+ def operate(self, sub_data: DataWithAxes):
153
+ """Extract info from sub-DataWithAxes
154
+
155
+ Retrieve the signal axis values of the minimum position of the data
156
+
157
+ Notes
158
+ -----
159
+ For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
160
+ (compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
161
+ the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
162
+ a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
163
+ dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
164
+ """
165
+ new_data_arrays = []
166
+ new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
167
+
168
+ for dat in flattened_arrays:
169
+ indexes = np.unravel_index(np.nanargmin(dat, len(new_shape)-1), sub_data.shape)[len(sub_data.nav_indexes):]
170
+ # from the unraveled index, retrieve the corresponding axis value
171
+ for ind in range(len(indexes)):
172
+ axis_data = sub_data.get_axis_from_index(sub_data.sig_indexes[ind])[0].get_data()
173
+ new_data_arrays.append(np.atleast_1d(axis_data[indexes[ind]]))
174
+ return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
175
+ axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes],
176
+ distribution=sub_data.distribution)
177
+
178
+
179
+ @DataProcessorFactory.register('argmean')
180
+ class ArgMeanProcessor(DataProcessorBase):
181
+ apply_to = DataDim['Data1D']
182
+
183
+ def operate(self, sub_data: DataWithAxes):
184
+ """Extract info from sub-DataWithAxes
185
+
186
+ Retrieve the signal mean axis values
187
+
188
+ Notes
189
+ -----
190
+ For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
191
+ (compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
192
+ the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
193
+ a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
194
+ dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
195
+ """
196
+ new_data_arrays = []
197
+ new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
198
+ values = sub_data.get_axis_from_index(sub_data.sig_indexes[0])[0].get_data()
199
+ for dat in flattened_arrays:
200
+ weights = dat
201
+ new_data_arrays.append(np.atleast_1d(np.average(values, axis=len(new_shape) - 1, weights=weights)))
202
+ return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
203
+ axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes])
204
+
205
+
206
+ @DataProcessorFactory.register('argstd')
207
+ class ArgStdProcessor(DataProcessorBase):
208
+ apply_to = DataDim['Data1D']
209
+
210
+ def operate(self, sub_data: DataWithAxes):
211
+ """Extract info from sub-DataWithAxes
212
+
213
+ Retrieve the signal mean axis values
214
+
215
+ Notes
216
+ -----
217
+ For more complex processors, such as the argmin, argmax ... , one cannot use directly the numpy function
218
+ (compared to min, max, mean...). Indeed one has to first flatten the data arrays on the signal axes, then apply
219
+ the function on the flatten dimension, here get the indexes of the minimum along the flattened dimension (as
220
+ a function of the eventual navigations dimensions). From this index, on then obtain as many indexes as signal
221
+ dimensions (1 for 1D Signals, 2 for 2D signals). And we do this for as many data there is in sub_data.
222
+ """
223
+ new_data_arrays = []
224
+ new_shape, flattened_arrays = self.flatten_signal_dim(sub_data)
225
+ values = sub_data.get_axis_from_index(sub_data.sig_indexes[0])[0].get_data()
226
+ for dat in flattened_arrays:
227
+ weights = dat
228
+ w_avg = np.atleast_1d(np.average(values, axis=len(new_shape) - 1, weights=weights))
229
+ new_data_arrays.append(np.atleast_1d(np.sqrt(
230
+ np.sum(weights * (values - w_avg) ** 2, axis=len(new_shape) - 1) /
231
+ np.sum(weights, axis=len(new_shape) - 1))))
232
+ return DataCalculated('processed_data', data=new_data_arrays, nav_indexes=sub_data.nav_indexes,
233
+ axes=[axis for axis in sub_data.axes if axis.index in sub_data.nav_indexes])
234
+
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created the 07/11/2022
4
+
5
+ @author: Sebastien Weber
6
+ """
7
+ from typing import Union, List, TYPE_CHECKING
8
+ import numpy as np
9
+
10
+ if TYPE_CHECKING:
11
+ from pymodaq_data import DataWithAxes, Axis
12
+
13
+
14
+ class SpecialSlicers(object):
15
+ """make it elegant to apply a slice to navigation or signal dimensions"""
16
+ def __init__(self, obj: Union['DataWithAxes', 'Axis'], is_navigation):
17
+ self.is_navigation = is_navigation
18
+ self.obj = obj
19
+
20
+ def __getitem__(self, slices) -> Union['DataWithAxes', 'Axis']:
21
+ return self.obj._slicer(slices, self.is_navigation)
22
+
23
+
24
+ class SpecialSlicersData(SpecialSlicers):
25
+
26
+ def __setitem__(self, slices, data: Union[np.ndarray, 'DataWithAxes', 'Axis']):
27
+ """x.__setitem__(slices, data) <==> x[slices]=data
28
+ """
29
+ slices = self.obj._compute_slices(slices, self.is_navigation)
30
+
31
+ if hasattr(self.obj, 'base_type') and self.obj.base_type == 'Axis':
32
+ if isinstance(data, np.ndarray):
33
+ data_to_replace = data
34
+ else:
35
+ data_to_replace = data.get_data()
36
+ if hasattr(self.obj, 'units') and self.obj.data is None:
37
+ self.obj.create_linear_data(len(self.obj))
38
+ self.obj.data[slices] = data_to_replace
39
+ else:
40
+ for ind in range(len(self.obj)):
41
+ if isinstance(data, np.ndarray):
42
+ data_to_replace = data
43
+ else: # means it's a DataWithAxes
44
+ data_to_replace = data[ind]
45
+ self.obj[ind][slices] = data_to_replace
46
+
47
+ def __len__(self):
48
+ return self.obj.axes_manager.sig_shape[0]
Binary file
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.3
2
+ Name: pymodaq_data
3
+ Version: 0.0.1
4
+ Summary: Modular Data Acquisition with Python
5
+ Project-URL: Homepage, http://pymodaq.cnrs.fr
6
+ Project-URL: Source, https://github.com/PyMoDAQ/PyMoDAQ
7
+ Project-URL: Tracker, https://github.com/PyMoDAQ/PyMoDAQ/issues
8
+ Author-email: Sébastien Weber <sebastien.weber@cemes.fr>
9
+ License: The MIT License (MIT)
10
+
11
+ Copyright (c) 2021 Sebastien Weber <sebastien.weber@cemes.fr>
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in
21
+ all copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
+ THE SOFTWARE.
30
+ License-File: LICENSE
31
+ Classifier: Development Status :: 5 - Production/Stable
32
+ Classifier: Environment :: Other Environment
33
+ Classifier: Intended Audience :: Science/Research
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Natural Language :: English
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3.7
38
+ Classifier: Programming Language :: Python :: 3.8
39
+ Classifier: Programming Language :: Python :: 3.9
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
43
+ Classifier: Topic :: Scientific/Engineering :: Visualization
44
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
45
+ Classifier: Topic :: Software Development :: User Interfaces
46
+ Requires-Python: >=3.8
47
+ Requires-Dist: multipledispatch
48
+ Requires-Dist: numpy<2.0.0
49
+ Requires-Dist: packaging
50
+ Requires-Dist: pint
51
+ Requires-Dist: pymodaq-utils
52
+ Requires-Dist: python-dateutil
53
+ Requires-Dist: scipy
54
+ Requires-Dist: tables<3.9
55
+ Requires-Dist: toml
56
+ Description-Content-Type: text/x-rst
57
+
58
+ PyMoDAQ Data
59
+ ############
60
+
61
+ .. image:: https://img.shields.io/pypi/v/pymodaq_data.svg
62
+ :target: https://pypi.org/project/pymodaq_data/
63
+ :alt: Latest Version
64
+
65
+ .. image:: https://readthedocs.org/projects/pymodaq/badge/?version=latest
66
+ :target: https://pymodaq.readthedocs.io/en/stable/?badge=latest
67
+ :alt: Documentation Status
68
+
69
+ .. image:: https://codecov.io/gh/PyMoDAQ/pymodaq_data/branch/0.0.x/graph/badge.svg?token=IQNJRCQDM2
70
+ :target: https://codecov.io/gh/PyMoDAQ/pymodaq_data
71
+
72
+ ====== ======= ======
73
+ Python OS Passed
74
+ ====== ======= ======
75
+ 3.8 Linux |38|
76
+ 3.9 Linux |39|
77
+ 3.10 Linux |310|
78
+ 3.11 Linux |311|
79
+ 3.12 Linux |312|
80
+ 3.11 Windows |311win|
81
+ ====== ======= ======
82
+
83
+
84
+ .. |38| image:: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp38.yml/badge.svg?branch=0.0.x_dev
85
+ :target: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp385.yml
86
+
87
+ .. |39| image:: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp39.yml/badge.svg?branch=0.0.x_dev
88
+ :target: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp39.yml
89
+
90
+ .. |310| image:: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp310.yml/badge.svg?branch=0.0.x_dev
91
+ :target: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp310.yml
92
+
93
+ .. |311| image:: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp311.yml/badge.svg?branch=0.0.x_dev
94
+ :target: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp311.yml
95
+
96
+ .. |312| image:: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp312.yml/badge.svg?branch=0.0.x_dev
97
+ :target: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp312.yml
98
+
99
+ .. |311win| image:: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp311_win.yml/badge.svg?branch=0.0.x_dev
100
+ :target: https://github.com/PyMoDAQ/pymodaq_data/actions/workflows/Testp311_win.yml
101
+
102
+
103
+
104
+
105
+ .. figure:: http://pymodaq.cnrs.fr/en/latest/_static/splash.png
106
+ :alt: shortcut
107
+
108
+
109
+ PyMoDAQ__, Modular Data Acquisition with Python, is a set of **python** modules used to interface any kind of
110
+ experiments. It simplifies the interaction with detector and actuator hardware to go straight to the data acquisition
111
+ of interest.
112
+
113
+ __ https://pymodaq.readthedocs.io/en/stable/?badge=latest
114
+
115
+ `PyMoDAQ data`__ is a set of utilities (constants, methods and classes) that are used
116
+ for Data Management. It is heavily used with the PyMoDAQ framework but can also be used as a standalone
117
+ package for data management in another context.
118
+
119
+ __ https://pymodaq.cnrs.fr/en/latest/developer_folder/data_management.html
120
+
121
+ What are Data?
122
+ --------------
123
+
124
+ Data are objects with many characteristics able to properly describe real data taken on an experiment
125
+ or calculated from theory:
126
+
127
+
128
+ * a type: float, int, ...
129
+ * a dimensionality: Data0D, Data1D, Data2D and higher
130
+ * units (dealt with the pint python package)
131
+ * axes
132
+ * actual data as numpy arrays
133
+ * uncertainty/error bars
134
+ * ...
135
+
136
+
137
+ .. figure:: https://pymodaq.cnrs.fr/en/latest/_images/data.png
138
+ :alt: What is data?
139
+
140
+ What is PyMoDAQ's data?.
141
+
142
+ The `PyMoDAQ Data` package
143
+ --------------------------
144
+
145
+ Because of this variety, `PyMoDAQ Data` introduce a set of objects including metadata (for instance the time of
146
+ acquisition) and various methods and properties to manipulate
147
+ them during analysis for instance (getting name, slicing, concatenating...),
148
+ save them and plot them (given you installed one of the available backend: *matplotlib* or *Qt* (
149
+ through the `pymodaq_gui` package)
150
+
151
+ To learn more, check the documentation__.
152
+
153
+ __ https://pymodaq.cnrs.fr/en/latest/developer_folder/data_management.html
154
+
155
+
156
+ Published under the MIT FREE SOFTWARE LICENSE
157
+
158
+ GitHub repo: https://github.com/PyMoDAQ
159
+
160
+ Documentation: http://pymodaq.cnrs.fr/
@@ -0,0 +1,26 @@
1
+ pymodaq_data/__init__.py,sha256=Eq4rIGouzYHyY3rWe1K8N4l_voPY5iRFTvW9wXI3f2E,1701
2
+ pymodaq_data/data.py,sha256=EEfjgNHcy-yS2Bzjurod7f5EWS8SRkY3-p6DlcybWEY,106030
3
+ pymodaq_data/icon.ico,sha256=hOHHfNDENKphQvG1WDleSEYcHukneR2eRFJu8isIlD4,74359
4
+ pymodaq_data/slicing.py,sha256=u-PDiCUFCpVzqf25KkC9ifnuZDKay2fWpaCytph15e4,1652
5
+ pymodaq_data/splash.png,sha256=ow8IECF3tPRUMA4tf2tMu1aRiMaxx91_Y2ckVxkrmF0,53114
6
+ pymodaq_data/h5modules/__init__.py,sha256=x3_4ELvG9onTKEFgIt9xEGg_mA1bB07dvVbU9q0xQKw,104
7
+ pymodaq_data/h5modules/backends.py,sha256=2svvkU_Jsqgm5XSP7uf1TlZZU8XMTgYEPgXe1d1ZYew,33798
8
+ pymodaq_data/h5modules/browsing.py,sha256=BRaR6qAy_pYRJe9hjWgl5HfyLBJ5dnygDghFCAWkdEg,3021
9
+ pymodaq_data/h5modules/data_saving.py,sha256=rvq9sLallgl-D-7M5ZYlpsgG3k_2TMK5FdIjYogEIjs,42570
10
+ pymodaq_data/h5modules/exporter.py,sha256=fkHGOy8ivzQ0hgn9hDJf7G4GWdTl6AdSTCJqvqzds0A,3669
11
+ pymodaq_data/h5modules/saving.py,sha256=ygZIccT4oprqwfkUA8C527iPS4Wbgrc6Mk90w8wwrSY,14599
12
+ pymodaq_data/h5modules/utils.py,sha256=yrCmPE7UAgZk4lanv4zC4LjTpp_vaQz54ZCvKWl15-0,3374
13
+ pymodaq_data/h5modules/exporters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ pymodaq_data/h5modules/exporters/base.py,sha256=U2DtIewbcaOGUDx0VGlhyqVpyjrx7KNVEvcg7S4NAxE,4117
15
+ pymodaq_data/h5modules/exporters/flimj.py,sha256=gUkbtTJGiv1LoK1WE0XZulqP9y57VWzjPaktXLmXZqs,2359
16
+ pymodaq_data/h5modules/exporters/hyperspy.py,sha256=gAMuMEuruVgbvk59L87Yc5b7kxwjXjaYbyAWW5dqH58,6513
17
+ pymodaq_data/plotting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ pymodaq_data/plotting/plotter/plotter.py,sha256=ueH_mg9bJnHCvl4MjM-hho4jG-G_sggMRhTBA_2Ns2Q,2839
19
+ pymodaq_data/plotting/plotter/plotters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ pymodaq_data/plotting/plotter/plotters/matplotlib_plotters.py,sha256=mUFgc2MTJTjq5jeTasP4xpB6Xli7QhOyfiK1gIVQlP8,5079
21
+ pymodaq_data/post_treatment/__init__.py,sha256=xaaLFZJ7OLqI_7yPurFk89A7m2ywSbYDXAsdE-QQ8Zg,81
22
+ pymodaq_data/post_treatment/process_to_scalar.py,sha256=hM2WmOesrkuWvq-BvNsZmKOz6_sZRJh97wdkVEgwqMc,10551
23
+ pymodaq_data-0.0.1.dist-info/METADATA,sha256=ssyXLUzmKiBGJsmuMZBu31c6_k3cT0ZFfixu8sYRsAs,6508
24
+ pymodaq_data-0.0.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
25
+ pymodaq_data-0.0.1.dist-info/licenses/LICENSE,sha256=VKOejxexXAe3XwfhAhcFGqeXQ12irxVHdeAojZwFEI8,1108
26
+ pymodaq_data-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.25.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Sebastien Weber <sebastien.weber@cemes.fr>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.