pymodaq 5.0.0__py3-none-any.whl → 5.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.

Potentially problematic release.


This version of pymodaq might be problematic. Click here for more details.

Files changed (60) hide show
  1. pymodaq/__init__.py +55 -89
  2. pymodaq/control_modules/daq_move.py +123 -52
  3. pymodaq/control_modules/daq_move_ui.py +42 -11
  4. pymodaq/control_modules/daq_viewer.py +30 -13
  5. pymodaq/control_modules/move_utility_classes.py +345 -78
  6. pymodaq/control_modules/utils.py +26 -9
  7. pymodaq/control_modules/viewer_utility_classes.py +51 -14
  8. pymodaq/daq_utils/daq_utils.py +6 -0
  9. pymodaq/dashboard.py +532 -263
  10. pymodaq/examples/qt_less_standalone_module.py +128 -0
  11. pymodaq/extensions/bayesian/bayesian_optimisation.py +30 -21
  12. pymodaq/extensions/bayesian/utils.py +6 -3
  13. pymodaq/extensions/daq_logger/__init__.py +1 -0
  14. pymodaq/extensions/daq_logger/daq_logger.py +4 -5
  15. pymodaq/extensions/daq_scan.py +1 -3
  16. pymodaq/extensions/daq_scan_ui.py +7 -9
  17. pymodaq/extensions/pid/__init__.py +0 -1
  18. pymodaq/extensions/pid/actuator_controller.py +13 -0
  19. pymodaq/extensions/pid/daq_move_PID.py +25 -46
  20. pymodaq/extensions/pid/pid_controller.py +48 -40
  21. pymodaq/extensions/pid/utils.py +3 -2
  22. pymodaq/extensions/utils.py +41 -7
  23. pymodaq/resources/setup_plugin.py +1 -0
  24. pymodaq/updater.py +107 -0
  25. pymodaq/utils/chrono_timer.py +6 -7
  26. pymodaq/utils/daq_utils.py +6 -3
  27. pymodaq/utils/data.py +11 -16
  28. pymodaq/utils/enums.py +6 -0
  29. pymodaq/utils/gui_utils/loader_utils.py +27 -2
  30. pymodaq/utils/gui_utils/utils.py +9 -12
  31. pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
  32. pymodaq/utils/leco/daq_move_LECODirector.py +21 -14
  33. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +13 -8
  34. pymodaq/utils/leco/pymodaq_listener.py +8 -7
  35. pymodaq/utils/leco/utils.py +33 -7
  36. pymodaq/utils/managers/modules_manager.py +20 -10
  37. pymodaq/utils/managers/overshoot_manager.py +45 -1
  38. pymodaq/utils/managers/preset_manager.py +22 -46
  39. pymodaq/utils/managers/preset_manager_utils.py +17 -13
  40. pymodaq/utils/managers/remote_manager.py +1 -1
  41. pymodaq/utils/messenger.py +6 -0
  42. pymodaq/utils/parameter/__init__.py +5 -1
  43. pymodaq/utils/tcp_ip/mysocket.py +4 -110
  44. pymodaq/utils/tcp_ip/serializer.py +4 -769
  45. pymodaq/utils/tcp_ip/tcp_server_client.py +5 -5
  46. pymodaq-5.0.1.dist-info/METADATA +242 -0
  47. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/RECORD +51 -52
  48. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/WHEEL +1 -1
  49. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/entry_points.txt +1 -0
  50. pymodaq/examples/custom_app.py +0 -255
  51. pymodaq/examples/custom_viewer.py +0 -112
  52. pymodaq/examples/parameter_ex.py +0 -158
  53. pymodaq/examples/preset_MockCamera.xml +0 -1
  54. pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py +0 -142
  55. pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui +0 -232
  56. pymodaq/post_treatment/daq_measurement/daq_measurement_main.py +0 -391
  57. pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -2
  58. pymodaq-5.0.0.dist-info/METADATA +0 -166
  59. /pymodaq/{post_treatment/daq_measurement → daq_utils}/__init__.py +0 -0
  60. {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,391 +0,0 @@
1
- from qtpy import QtWidgets
2
- from qtpy.QtCore import Qt, QObject, Slot, Signal
3
-
4
- import sys
5
- from pymodaq.post_treatment.daq_measurement.daq_measurement_GUI import Ui_Form
6
- from pymodaq.utils import daq_utils as utils
7
- from pymodaq.utils.plotting.utils.filter import FourierFilterer
8
- from scipy.optimize import curve_fit
9
- import numpy as np
10
- from pymodaq.utils.enums import BaseEnum
11
-
12
-
13
- class Measurement_type(BaseEnum):
14
- Cursor_Integration = 0
15
- Max = 1
16
- Min = 2
17
- Gaussian_Fit = 3
18
- Lorentzian_Fit = 4
19
- Exponential_Decay_Fit = 5
20
- Sinus = 6
21
-
22
- @classmethod
23
- def update_measurement_subtype(cls, mtype):
24
- measurement_gaussian_subitems = ["amp", "dx", "x0", "offset"]
25
- measurement_laurentzian_subitems = ["alpha", "gamma", "x0", "offset"]
26
- measurement_decay_subitems = ["N0", "gamma", 'x0', "offset"]
27
- measurement_cursor_subitems = ["sum", "mean", "std"]
28
- measurement_sinus_subtitems = ['A', 'dx', 'phi', 'offset']
29
- variables = ", "
30
- formula = ""
31
- subitems = []
32
- if mtype == 'Cursor_Integration': # "Cursor integration":
33
- subitems = measurement_cursor_subitems
34
-
35
- if mtype == 'Gaussian_Fit': # "Gaussian Fit":
36
- subitems = measurement_gaussian_subitems
37
- formula = "amp*np.exp(-2*np.log(2)*(x-x0)**2/dx**2)+offset"
38
- variables = variables.join(measurement_gaussian_subitems)
39
-
40
- elif mtype == 'Lorentzian_Fit': # "Lorentzian Fit":
41
- subitems = measurement_laurentzian_subitems
42
- variables = variables.join(measurement_laurentzian_subitems)
43
- formula = "alpha/np.pi*gamma/2/((x-x0)**2+(gamma/2)**2)+offset"
44
-
45
- elif mtype == 'Exponential_Decay_Fit': # "Exponential Decay Fit":
46
- subitems = measurement_decay_subitems
47
- variables = variables.join(measurement_decay_subitems)
48
- formula = "N0*np.exp(-(x-x0)/gamma)+offset"
49
-
50
- elif mtype == 'Sinus':
51
- subitems = measurement_sinus_subtitems
52
- variables = variables.join(measurement_sinus_subtitems)
53
- formula = "A*np.sin(2*np.pi*x/dx-phi)+offset"
54
-
55
- return [variables, formula, subitems]
56
-
57
- def gaussian_func(self, x, amp, dx, x0, offset):
58
- return amp * np.exp(-2 * np.log(2) * (x - x0) ** 2 / dx ** 2) + offset
59
-
60
- def laurentzian_func(self, x, alpha, gamma, x0, offset):
61
- return alpha / np.pi * 1 / 2 * gamma / ((x - x0) ** 2 + (1 / 2 * gamma) ** 2) + offset
62
-
63
- def decaying_func(self, x, N0, gamma, x0, offset):
64
- return N0 * np.exp(-(x - x0) / gamma) + offset
65
-
66
- def sinus_func(self, x, A, dx, phi, offset):
67
- return A * np.sin(2 * np.pi * x / dx - phi) + offset
68
-
69
-
70
- class DAQ_Measurement(Ui_Form, QObject):
71
- """
72
- =================== ================================== =======================================
73
- **Attributes** **Type** **Description**
74
-
75
-
76
- *ui* QObject The local instance of User Interface
77
- *wait_time* int The default delay of showing
78
- *parent* QObject The QObject initializing the UI
79
- *xdata* 1D numpy array The x axis data
80
- *ydata* 1D numpy array The y axis data
81
- *measurement_types* instance of daq_utils.DAQ_enums The type of the measurement, between:
82
- * 'Cursor_Integration'
83
- * 'Max'
84
- * 'Min'
85
- * 'Gaussian_Fit'
86
- * 'Lorentzian_Fit'
87
- * 'Exponential_Decay_Fit'
88
- =================== ================================== =======================================
89
-
90
- References
91
- ----------
92
- Ui_Form, QObject, qtpy, pyqtgraph
93
- """
94
- measurement_signal = Signal(list)
95
-
96
- def __init__(self, parent):
97
-
98
- super(Ui_Form, self).__init__()
99
- self.ui = Ui_Form()
100
- self.ui.setupUi(parent)
101
-
102
- self.widg = QtWidgets.QWidget()
103
- self.fourierfilt = FourierFilterer(self.widg)
104
- self.ui.splitter_2.addWidget(self.widg)
105
- self.ui.graph1D = self.fourierfilt.viewer1D.plotwidget
106
- QtWidgets.QApplication.processEvents()
107
-
108
- self.ui.splitter.setSizes([200, 400])
109
- self.ui.statusbar = QtWidgets.QStatusBar(parent)
110
- self.ui.statusbar.setMaximumHeight(15)
111
- self.ui.StatusBarLayout.addWidget(self.ui.statusbar)
112
- self.wait_time = 1000
113
- self.parent = parent
114
- self.xdata = None
115
- self.ydata = None
116
-
117
- self.measurement_types = Measurement_type.names()
118
- self.measurement_type = Measurement_type(0)
119
- self.ui.measurement_type_combo.clear()
120
- self.ui.measurement_type_combo.addItems(self.measurement_types)
121
-
122
- self.ui.fit_curve = self.fourierfilt.viewer1D.plotwidget.plot()
123
- self.ui.fit_curve.setPen("y")
124
- self.ui.fit_curve.setVisible(False)
125
-
126
- self.ui.selected_region = self.fourierfilt.viewer1D.ROI
127
- self.ui.selected_region.setZValue(-10)
128
- self.ui.selected_region.setBrush('b')
129
- self.ui.selected_region.setOpacity(0.2)
130
- self.ui.selected_region.setVisible(True)
131
- self.fourierfilt.viewer1D.plotwidget.addItem(self.ui.selected_region)
132
-
133
- # Connecting buttons:
134
- self.ui.Quit_pb.clicked.connect(self.Quit_fun, type=Qt.QueuedConnection)
135
- self.ui.measurement_type_combo.currentTextChanged[str].connect(self.update_measurement_subtype)
136
- self.ui.measure_subtype_combo.currentTextChanged[str].connect(self.update_measurement)
137
- self.update_measurement_subtype(self.ui.measurement_type_combo.currentText(), update=False)
138
- self.ui.selected_region.sigRegionChanged.connect(self.update_measurement)
139
- self.ui.result_sb.valueChanged.connect(self.ui.result_lcd.display)
140
-
141
- @Slot(dict)
142
- def update_fft_filter(self, d):
143
- self.frequency = d['frequency']
144
- self.phase = d['phase']
145
- self.update_measurement()
146
-
147
- def Quit_fun(self):
148
- """
149
- close the current instance of daq_measurement.
150
-
151
- """
152
- # insert anything that needs to be closed before leaving
153
- self.parent.close()
154
-
155
- def update_status(self, txt, wait_time=0):
156
- """
157
- Update the statut bar showing the given text message with a delay of wait_time ms (0s by default).
158
-
159
- =============== ========= ===========================
160
- **Parameters**
161
-
162
- *txt* string the text message to show
163
-
164
- *wait_time* int the delay time of waiting
165
- =============== ========= ===========================
166
-
167
- """
168
- self.ui.statusbar.showMessage(txt, wait_time)
169
-
170
- @Slot(str)
171
- def update_measurement_subtype(self, mtype, update=True):
172
- """
173
- | Update the ui-measure_subtype_combo from subitems and formula attributes, if specified by update parameter.
174
- | Linked with the update_measurement method
175
-
176
- ================ ========== =====================================================================================
177
- **Parameters** **Type** **Description**
178
-
179
- mtype string the Measurement_type index of the Measurement_type array (imported from daq_utils)
180
-
181
- update boolean the update boolean link with the update_measurement method
182
- ================ ========== =====================================================================================
183
-
184
- See Also
185
- --------
186
- update_measurement_subtype, update_measurement, update_status
187
-
188
- """
189
- self.measurement_type = Measurement_type[mtype]
190
- [variables, self.formula, self.subitems] = Measurement_type.update_measurement_subtype(mtype)
191
-
192
- try:
193
- self.ui.measure_subtype_combo.clear()
194
- self.ui.measure_subtype_combo.addItems(self.subitems)
195
- self.ui.formula_edit.setPlainText(self.formula)
196
-
197
- if update:
198
- self.update_measurement()
199
- except Exception as e:
200
- self.update_status(str(e), wait_time=self.wait_time)
201
-
202
- def update_measurement(self):
203
- """
204
- Update :
205
- * the measurement results from the update_measurements method
206
- * the statut bar on cascade (if needed)
207
- * the User Interface function curve state and data (if needed).
208
-
209
- Emit the measurement_signal corresponding.
210
-
211
- See Also
212
- --------
213
- update_measurement, update_status
214
-
215
- """
216
- try:
217
- xlimits = self.ui.selected_region.getRegion()
218
- mtype = self.ui.measurement_type_combo.currentText()
219
- msubtype = self.ui.measure_subtype_combo.currentText()
220
- if mtype == 'Sinus':
221
-
222
- # boundaries = utils.find_index(self.xdata, [xlimits[0], xlimits[1]])
223
- # sub_xaxis = self.xdata[boundaries[0][0]:boundaries[1][0]]
224
- # sub_data = self.ydata[boundaries[0][0]:boundaries[1][0]]
225
- # self.fourierfilt.parent.setVisible(True)
226
- self.fourierfilt.show_data(dict(data=self.ydata, xaxis=self.xdata))
227
- else:
228
- # self.fourierfilt.parent.setVisible(False)
229
- pass
230
-
231
- measurement_results = self.do_measurement(xlimits[0], xlimits[1], self.xdata, self.ydata, mtype, msubtype)
232
- if measurement_results['status'] is not None:
233
- self.update_status(measurement_results['status'], wait_time=self.wait_time)
234
- return
235
- self.ui.result_sb.setValue(measurement_results['value'])
236
- self.measurement_signal.emit([measurement_results['value']])
237
- if measurement_results['datafit'] is not None:
238
- self.ui.fit_curve.setVisible(True)
239
- self.ui.fit_curve.setData(measurement_results['xaxis'], measurement_results['datafit'])
240
- else:
241
- self.ui.fit_curve.setVisible(False)
242
- except Exception as e:
243
- self.update_status(str(e), wait_time=self.wait_time)
244
-
245
- def eval_func(self, x, *args):
246
- dic = dict(zip(self.subitems, args))
247
- dic.update(dict(np=np, x=x))
248
- return eval(self.formula, dic)
249
-
250
- def do_measurement(self, xmin, xmax, xaxis, data1D, mtype, msubtype):
251
- try:
252
- boundaries = utils.find_index(xaxis, [xmin, xmax])
253
- sub_xaxis = xaxis[boundaries[0][0]:boundaries[1][0]]
254
- sub_data = data1D[boundaries[0][0]:boundaries[1][0]]
255
- mtypes = Measurement_type.names()
256
- if msubtype in self.subitems:
257
- msub_ind = self.subitems.index(msubtype)
258
-
259
- measurement_results = dict(status=None, value=0, xaxis=np.array([]), datafit=np.array([]))
260
-
261
- if mtype == 'Cursor_Integration': # "Cursor Intensity Integration":
262
- if msubtype == "sum":
263
- result_measurement = np.sum(sub_data)
264
- elif msubtype == "mean":
265
- result_measurement = np.mean(sub_data)
266
- elif msubtype == "std":
267
- result_measurement = np.std(sub_data)
268
- else:
269
- result_measurement = 0
270
-
271
- elif mtype == 'Max': # "Max":
272
- result_measurement = np.max(sub_data)
273
-
274
- elif mtype == 'Min': # "Min":
275
- result_measurement = np.min(sub_data)
276
-
277
- elif mtype == 'Gaussian_Fit': # "Gaussian Fit":
278
- measurement_results['xaxis'] = sub_xaxis
279
- offset = np.min(sub_data)
280
- amp = np.max(sub_data) - np.min(sub_data)
281
- m = utils.my_moment(sub_xaxis, sub_data)
282
- p0 = [amp, m[1], m[0], offset]
283
- popt, pcov = curve_fit(self.eval_func, sub_xaxis, sub_data, p0=p0)
284
- measurement_results['datafit'] = self.eval_func(sub_xaxis, *popt)
285
- result_measurement = popt[msub_ind]
286
-
287
- elif mtype == 'Lorentzian_Fit': # "Lorentzian Fit":
288
- measurement_results['xaxis'] = sub_xaxis
289
- offset = np.min(sub_data)
290
- amp = np.max(sub_data) - np.min(sub_data)
291
- m = utils.my_moment(sub_xaxis, sub_data)
292
- p0 = [amp, m[1], m[0], offset]
293
- popt, pcov = curve_fit(self.eval_func, sub_xaxis, sub_data, p0=p0)
294
- measurement_results['datafit'] = self.eval_func(sub_xaxis, *popt)
295
- if msub_ind == 4: # amplitude
296
- result_measurement = popt[0] * 2 / (np.pi * popt[1]) # 2*alpha/(pi*gamma)
297
- else:
298
- result_measurement = popt[msub_ind]
299
-
300
- elif mtype == 'Exponential_Decay_Fit': # "Exponential Decay Fit":
301
- ind_x0 = utils.find_index(sub_data, np.max(sub_data))[0][0]
302
- x0 = sub_xaxis[ind_x0]
303
- sub_xaxis = sub_xaxis[ind_x0:]
304
- sub_data = sub_data[ind_x0:]
305
- offset = min([sub_data[0], sub_data[-1]])
306
- measurement_results['xaxis'] = sub_xaxis
307
- N0 = np.max(sub_data) - offset
308
- t37 = sub_xaxis[utils.find_index(sub_data - offset, 0.37 * N0)[0][0]] - x0
309
- # polynome = np.polyfit(sub_xaxis, -np.log((sub_data - 0.99 * offset) / N0), 1)
310
- p0 = [N0, t37, x0, offset]
311
- popt, pcov = curve_fit(self.eval_func, sub_xaxis, sub_data, p0=p0)
312
- measurement_results['datafit'] = self.eval_func(sub_xaxis, *popt)
313
- result_measurement = popt[msub_ind]
314
-
315
- elif mtype == 'Sinus': #
316
- offset = np.mean(sub_data)
317
- A = (np.max(sub_data) - np.min(sub_data)) / 2
318
- phi = self.fourierfilt.phase
319
- dx = 1 / self.fourierfilt.frequency
320
- measurement_results['xaxis'] = sub_xaxis
321
- p0 = [A, dx, phi, offset]
322
- popt, pcov = curve_fit(self.eval_func, sub_xaxis, sub_data, p0=p0)
323
- measurement_results['datafit'] = self.eval_func(sub_xaxis, *popt)
324
- result_measurement = popt[msub_ind]
325
-
326
- # elif mtype=="Custom Formula":
327
- # #offset=np.min(sub_data)
328
- # #amp=np.max(sub_data)-np.min(sub_data)
329
- # #m=utils.my_moment(sub_xaxis,sub_data)
330
- # #p0=[amp,m[1],m[0],offset]
331
- # popt, pcov = curve_fit(self.custom_func, sub_xaxis, sub_data,p0=[140,750,50,15])
332
- # self.curve_fitting_sig.emit([sub_xaxis,self.gaussian_func(sub_xaxis,*popt)])
333
- # result_measurement=popt[msub_ind]
334
- else:
335
- result_measurement = 0
336
-
337
- measurement_results['value'] = result_measurement
338
-
339
- return measurement_results
340
- except Exception as e:
341
- result_measurement = 0
342
- measurement_results['status'] = str(e)
343
- return measurement_results
344
-
345
- def update_data(self, xdata=None, ydata=None):
346
- """
347
- | Update xdata attribute with the numpy linspcae regular distribution (if param is none) and update the User Interface curve data.
348
- | Call the update_measurement method synchronously to keep same values.
349
-
350
- =============== ============ ======================
351
- **Parameters** **Type** **Description**
352
-
353
- *xdata* float list the x axis data
354
- *ydata* float list the y axis data
355
- =============== ============ ======================
356
-
357
- See Also
358
- --------
359
- update_measurement
360
-
361
- """
362
- if xdata is None:
363
- self.xdata = np.linspace(0, len(ydata) - 1, len(ydata))
364
- else:
365
- self.xdata = xdata
366
- self.ydata = ydata
367
- self.fourierfilt.show_data(dict(data=self.ydata, xaxis=self.xdata))
368
- self.update_measurement()
369
-
370
-
371
- if __name__ == '__main__':
372
- app = QtWidgets.QApplication(sys.argv)
373
- Form = QtWidgets.QWidget()
374
- from pymodaq.utils.daq_utils import gauss1D
375
-
376
- prog = DAQ_Measurement(Form)
377
- xdata = np.linspace(0, 400, 401)
378
- x0 = 50
379
- dx = 20
380
- tau = 27
381
- tau2 = 100
382
- ydata_gauss = 10 * gauss1D(xdata, x0, dx) + np.random.rand(len(xdata))
383
- ydata_expodec = np.zeros((len(xdata)))
384
- ydata_expodec[:50] = 10 * gauss1D(xdata[:50], x0, dx, 2)
385
- ydata_expodec[50:] = 10 * np.exp(-(xdata[50:] - x0) / tau) # +10*np.exp(-(xdata[50:]-x0)/tau2)
386
- ydata_expodec += 2 * np.random.rand(len(xdata))
387
- ydata_sin = 10 + 2 * np.sin(2 * np.pi * xdata / 21 - np.deg2rad(55)) + 2 * np.random.rand(len(xdata))
388
- prog.update_data(xdata, ydata_sin)
389
- Form.show()
390
-
391
- sys.exit(app.exec_())
@@ -1,2 +0,0 @@
1
- cd "C:\DAQ\Python\PyMoDAQ_Git\pymodaq\pymodaq\daq_measurement"
2
- C:\WPy-3710\python-3.7.1.amd64\Scripts\pyuic5.bat -x DAQ_Measurement_GUI.ui -o DAQ_Measurement_GUI.py
@@ -1,166 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: pymodaq
3
- Version: 5.0.0
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.8
38
- Classifier: Programming Language :: Python :: 3.9
39
- Classifier: Programming Language :: Python :: 3.10
40
- Classifier: Programming Language :: Python :: 3.11
41
- Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
42
- Classifier: Topic :: Scientific/Engineering :: Visualization
43
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
44
- Classifier: Topic :: Software Development :: User Interfaces
45
- Requires-Python: >=3.8
46
- Requires-Dist: bayesian-optimization
47
- Requires-Dist: easydict
48
- Requires-Dist: importlib-metadata; python_version < '3.8'
49
- Requires-Dist: multipledispatch
50
- Requires-Dist: numpy<2.0.0
51
- Requires-Dist: packaging
52
- Requires-Dist: pint
53
- Requires-Dist: pyleco; python_version >= '3.8'
54
- Requires-Dist: pymodaq-data
55
- Requires-Dist: pymodaq-gui
56
- Requires-Dist: pymodaq-plugin-manager>=0.0.17
57
- Requires-Dist: pymodaq-plugins-mock
58
- Requires-Dist: pymodaq-utils
59
- Requires-Dist: pyqtgraph>=0.12
60
- Requires-Dist: python-dateutil
61
- Requires-Dist: qdarkstyle
62
- Requires-Dist: qtconsole
63
- Requires-Dist: qtpy
64
- Requires-Dist: scipy
65
- Requires-Dist: setuptools>=60
66
- Requires-Dist: simple-pid
67
- Requires-Dist: tables<3.9
68
- Requires-Dist: toml
69
- Description-Content-Type: text/x-rst
70
-
71
- PyMoDAQ
72
- #######
73
-
74
- .. image:: https://img.shields.io/pypi/v/pymodaq.svg
75
- :target: https://pypi.org/project/pymodaq/
76
- :alt: Latest Version
77
-
78
- .. image:: https://readthedocs.org/projects/pymodaq/badge/?version=latest
79
- :target: https://pymodaq.readthedocs.io/en/stable/?badge=latest
80
- :alt: Documentation Status
81
-
82
- .. image:: https://codecov.io/gh/PyMoDAQ/PyMoDAQ/branch/pymodaq-dev/graph/badge.svg?token=IQNJRCQDM2
83
- :target: https://codecov.io/gh/PyMoDAQ/PyMoDAQ
84
-
85
- ====== ========== ======= ======
86
- Python Qt Backend OS Passed
87
- ====== ========== ======= ======
88
- 3.8 Qt5 Linux |38Qt5|
89
- 3.9 Qt5 Linux |39Qt5|
90
- 3.10 Qt5 Linux |310Qt5|
91
- 3.11 Qt5 Linux |311Qt5|
92
- 3.8 Qt5 Windows |38Qt5win|
93
- 3.8 PySide2 Linux |38pyside|
94
- 3.9 Qt6 Linux |39Qt6|
95
- ====== ========== ======= ======
96
-
97
-
98
- .. |38Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5.yml/badge.svg?branch=pymodaq-dev
99
- :target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5.yml
100
-
101
- .. |39Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt5.yml/badge.svg?branch=pymodaq-dev
102
- :target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt5.yml
103
-
104
- .. |310Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp310pyqt5.yml/badge.svg?branch=pymodaq-dev
105
- :target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp310pyqt5.yml
106
-
107
- .. |311Qt5| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp311pyqt5.yml/badge.svg?branch=pymodaq-dev
108
- :target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp311pyqt5.yml
109
-
110
- .. |38Qt5win| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5_win.yml/badge.svg?branch=pymodaq-dev
111
- :target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyqt5_win.yml
112
-
113
- .. |38pyside| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyside2.yml/badge.svg?branch=pymodaq-dev
114
- :target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp38pyside2.yml
115
-
116
- .. |39Qt6| image:: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt6.yml/badge.svg?branch=pymodaq-dev
117
- :target: https://github.com/PyMoDAQ/PyMoDAQ/actions/workflows/Testp39pyqt6.yml
118
-
119
-
120
-
121
- .. figure:: http://pymodaq.cnrs.fr/en/latest/_static/splash.png
122
- :alt: shortcut
123
-
124
-
125
- PyMoDAQ, Modular Data Acquisition with Python, is a set of **python** modules used to interface any kind of experiments.
126
- It simplifies the interaction with detector and actuator hardware to go straight to the data acquisition of interest.
127
-
128
- It has two purposes:
129
-
130
- * First, to provide a complete interface to perform automated measurements or logging data without having to write a user/interface for each
131
- new experiment, this is under the *Dashboard_module* environment and its extensions.
132
- * Second, to provide various tools (modules) to easily build *custom apps*
133
-
134
- It is organised a shown below:
135
-
136
- .. figure:: http://pymodaq.cnrs.fr/en/latest/_images/pymodaq_diagram.png
137
- :alt: overview
138
-
139
- PyMoDAQ's Dashboard and its extensions: DAQ_Scan for automated acquisitions, DAQ_Logger for data logging and many other.
140
-
141
- The main component is the **Dashboard** : This is a graphical component that will initialize actuators and detectors given
142
- the need of your particular experiment. You configure the dashboard using an interface for quick launch of various
143
- configurations (numbers and types of control modules).
144
-
145
- The detectors and the actuators are represented and manipulated using two control modules:
146
-
147
- * **DAQ_Move_module** : used to control/drive an actuator (stand alone and/or automated).
148
- Any number of these modules can be instantiated in the Dashboard
149
- * **DAQ_Viewer_module** : used to control/drive a detector (stand alone and/or automated).
150
-
151
- Any number of these modules can be instantiated in the Dashboard.
152
-
153
- The Dashboard allows you to start dedicated extensions that will make use of the control modules:
154
-
155
- * **DAQ_Logger_module** : This module lets you log data from one or many detectors defined in the dashboard. You can log data
156
- in a binary hierarchical hdf5 file or towards a sql database
157
- * **DAQ_Scan_module** : This module lets you configure automated data acquisition from one or many detectors defined
158
- in the dashboard as a function or one or more actuators defined also in the dashboard.
159
-
160
- and many others to simplify any application development.
161
-
162
- Published under the MIT FREE SOFTWARE LICENSE
163
-
164
- GitHub repo: https://github.com/PyMoDAQ
165
-
166
- Documentation: http://pymodaq.cnrs.fr/