pymodaq 3.6.13__py3-none-any.whl → 4.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 (233) hide show
  1. pymodaq/__init__.py +13 -6
  2. pymodaq/control_modules/__init__.py +0 -7
  3. pymodaq/control_modules/daq_move.py +965 -2
  4. pymodaq/control_modules/daq_move_ui.py +319 -0
  5. pymodaq/control_modules/daq_viewer.py +1573 -3
  6. pymodaq/control_modules/daq_viewer_ui.py +393 -0
  7. pymodaq/control_modules/mocks.py +51 -0
  8. pymodaq/control_modules/move_utility_classes.py +709 -8
  9. pymodaq/control_modules/utils.py +256 -0
  10. pymodaq/control_modules/viewer_utility_classes.py +663 -6
  11. pymodaq/daq_utils.py +89 -0
  12. pymodaq/dashboard.py +91 -72
  13. pymodaq/examples/custom_app.py +12 -11
  14. pymodaq/examples/custom_viewer.py +10 -10
  15. pymodaq/examples/function_plotter.py +16 -13
  16. pymodaq/examples/nonlinearscanner.py +8 -6
  17. pymodaq/examples/parameter_ex.py +7 -7
  18. pymodaq/examples/preset_MockCamera.xml +1 -0
  19. pymodaq/extensions/__init__.py +16 -0
  20. pymodaq/extensions/console.py +76 -0
  21. pymodaq/{daq_logger.py → extensions/daq_logger.py} +115 -65
  22. pymodaq/extensions/daq_scan.py +1339 -0
  23. pymodaq/extensions/daq_scan_ui.py +240 -0
  24. pymodaq/extensions/h5browser.py +23 -0
  25. pymodaq/{pid → extensions/pid}/__init__.py +4 -2
  26. pymodaq/{pid → extensions/pid}/daq_move_PID.py +2 -2
  27. pymodaq/{pid → extensions/pid}/pid_controller.py +48 -36
  28. pymodaq/{pid → extensions/pid}/utils.py +52 -6
  29. pymodaq/extensions/utils.py +40 -0
  30. pymodaq/post_treatment/__init__.py +6 -0
  31. pymodaq/{daq_analysis → post_treatment/daq_analysis}/daq_analysis_main.py +17 -17
  32. pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_main.py +8 -14
  33. pymodaq/post_treatment/load_and_plot.py +219 -0
  34. pymodaq/post_treatment/process_to_scalar.py +263 -0
  35. pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
  36. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
  37. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +1 -1
  38. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +1 -0
  39. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +109784 -109173
  40. pymodaq/resources/QtDesigner_Ressources/icons.svg +142 -0
  41. pymodaq/resources/VERSION +1 -1
  42. pymodaq/resources/config_template.toml +32 -13
  43. pymodaq/resources/preset_default.xml +1 -1
  44. pymodaq/{daq_utils → utils}/Tuto innosetup/script_full_setup.iss +1 -1
  45. pymodaq/utils/__init__.py +0 -29
  46. pymodaq/utils/abstract/__init__.py +48 -0
  47. pymodaq/{daq_utils → utils}/abstract/logger.py +7 -3
  48. pymodaq/utils/array_manipulation.py +379 -8
  49. pymodaq/{daq_utils → utils}/calibration_camera.py +6 -6
  50. pymodaq/{daq_utils → utils}/chrono_timer.py +1 -1
  51. pymodaq/utils/config.py +448 -0
  52. pymodaq/utils/conftests.py +5 -0
  53. pymodaq/utils/daq_utils.py +828 -8
  54. pymodaq/utils/data.py +1873 -7
  55. pymodaq/{daq_utils → utils}/db/db_logger/db_logger.py +86 -47
  56. pymodaq/{daq_utils → utils}/db/db_logger/db_logger_models.py +31 -10
  57. pymodaq/{daq_utils → utils}/enums.py +12 -7
  58. pymodaq/utils/exceptions.py +37 -0
  59. pymodaq/utils/factory.py +82 -0
  60. pymodaq/{daq_utils → utils}/gui_utils/__init__.py +1 -1
  61. pymodaq/utils/gui_utils/custom_app.py +129 -0
  62. pymodaq/utils/gui_utils/file_io.py +66 -0
  63. pymodaq/{daq_utils → utils}/gui_utils/layout.py +2 -2
  64. pymodaq/{daq_utils → utils}/gui_utils/utils.py +13 -3
  65. pymodaq/{daq_utils → utils}/gui_utils/widgets/__init__.py +2 -2
  66. pymodaq/utils/gui_utils/widgets/label.py +24 -0
  67. pymodaq/{daq_utils → utils}/gui_utils/widgets/lcd.py +12 -7
  68. pymodaq/{daq_utils → utils}/gui_utils/widgets/push.py +66 -2
  69. pymodaq/{daq_utils → utils}/gui_utils/widgets/qled.py +6 -4
  70. pymodaq/utils/gui_utils/widgets/spinbox.py +24 -0
  71. pymodaq/{daq_utils → utils}/gui_utils/widgets/table.py +2 -2
  72. pymodaq/utils/h5modules/__init__.py +1 -0
  73. pymodaq/{daq_utils/h5backend.py → utils/h5modules/backends.py} +200 -112
  74. pymodaq/utils/h5modules/browsing.py +683 -0
  75. pymodaq/utils/h5modules/data_saving.py +839 -0
  76. pymodaq/utils/h5modules/h5logging.py +110 -0
  77. pymodaq/utils/h5modules/module_saving.py +350 -0
  78. pymodaq/utils/h5modules/saving.py +914 -0
  79. pymodaq/utils/h5modules/utils.py +85 -0
  80. pymodaq/utils/logger.py +64 -6
  81. pymodaq/utils/managers/action_manager.py +460 -0
  82. pymodaq/{daq_utils → utils}/managers/batchscan_manager.py +144 -112
  83. pymodaq/{daq_utils → utils}/managers/modules_manager.py +188 -114
  84. pymodaq/{daq_utils → utils}/managers/overshoot_manager.py +3 -3
  85. pymodaq/utils/managers/parameter_manager.py +110 -0
  86. pymodaq/{daq_utils → utils}/managers/preset_manager.py +17 -13
  87. pymodaq/{daq_utils → utils}/managers/preset_manager_utils.py +8 -7
  88. pymodaq/{daq_utils → utils}/managers/remote_manager.py +7 -6
  89. pymodaq/{daq_utils → utils}/managers/roi_manager.py +148 -57
  90. pymodaq/utils/math_utils.py +546 -10
  91. pymodaq/{daq_utils → utils}/messenger.py +5 -1
  92. pymodaq/utils/parameter/__init__.py +2 -15
  93. pymodaq/{daq_utils → utils}/parameter/ioxml.py +12 -6
  94. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/__init__.py +1 -3
  95. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/filedir.py +1 -1
  96. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/itemselect.py +3 -0
  97. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/led.py +1 -1
  98. pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +161 -0
  99. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/slide.py +1 -1
  100. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/table.py +1 -1
  101. pymodaq/utils/parameter/utils.py +206 -11
  102. pymodaq/utils/plotting/data_viewers/__init__.py +6 -0
  103. pymodaq/utils/plotting/data_viewers/viewer.py +393 -0
  104. pymodaq/utils/plotting/data_viewers/viewer0D.py +251 -0
  105. pymodaq/utils/plotting/data_viewers/viewer1D.py +574 -0
  106. pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer1Dbasic.py +8 -3
  107. pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D.py +292 -357
  108. pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D_basic.py +58 -75
  109. pymodaq/utils/plotting/data_viewers/viewerND.py +738 -0
  110. pymodaq/{daq_utils → utils}/plotting/gant_chart.py +2 -2
  111. pymodaq/{daq_utils → utils}/plotting/items/axis_scaled.py +4 -2
  112. pymodaq/{daq_utils → utils}/plotting/items/image.py +8 -6
  113. pymodaq/utils/plotting/navigator.py +355 -0
  114. pymodaq/utils/plotting/scan_selector.py +480 -0
  115. pymodaq/utils/plotting/utils/axes_viewer.py +88 -0
  116. pymodaq/utils/plotting/utils/filter.py +538 -0
  117. pymodaq/utils/plotting/utils/lineout.py +224 -0
  118. pymodaq/{daq_utils → utils}/plotting/utils/plot_utils.py +196 -84
  119. pymodaq/{daq_utils → utils}/plotting/utils/signalND.py +21 -13
  120. pymodaq/utils/plotting/widgets.py +76 -0
  121. pymodaq/utils/scanner/__init__.py +10 -0
  122. pymodaq/utils/scanner/scan_factory.py +204 -0
  123. pymodaq/utils/scanner/scanner.py +271 -0
  124. pymodaq/utils/scanner/scanners/_1d_scanners.py +117 -0
  125. pymodaq/utils/scanner/scanners/_2d_scanners.py +293 -0
  126. pymodaq/utils/scanner/scanners/sequential.py +192 -0
  127. pymodaq/utils/scanner/scanners/tabular.py +294 -0
  128. pymodaq/utils/scanner/utils.py +83 -0
  129. pymodaq/utils/slicing.py +47 -0
  130. pymodaq/utils/svg/__init__.py +6 -0
  131. pymodaq/utils/svg/svg_renderer.py +20 -0
  132. pymodaq/utils/svg/svg_view.py +35 -0
  133. pymodaq/utils/svg/svg_viewer2D.py +51 -0
  134. pymodaq/{daq_utils → utils}/tcp_server_client.py +36 -37
  135. pymodaq/{daq_utils → utils}/tree_layout/tree_layout_main.py +50 -35
  136. pymodaq/utils/units.py +216 -0
  137. pymodaq-4.0.1.dist-info/METADATA +159 -0
  138. {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
  139. {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/WHEEL +1 -2
  140. pymodaq-4.0.1.dist-info/entry_points.txt +8 -0
  141. pymodaq/daq_move/daq_move_gui.py +0 -279
  142. pymodaq/daq_move/daq_move_gui.ui +0 -534
  143. pymodaq/daq_move/daq_move_main.py +0 -1042
  144. pymodaq/daq_move/process_from_QtDesigner_DAQ_Move_GUI.bat +0 -2
  145. pymodaq/daq_move/utility_classes.py +0 -686
  146. pymodaq/daq_scan.py +0 -2160
  147. pymodaq/daq_utils/array_manipulation.py +0 -386
  148. pymodaq/daq_utils/config.py +0 -273
  149. pymodaq/daq_utils/conftests.py +0 -7
  150. pymodaq/daq_utils/custom_parameter_tree.py +0 -9
  151. pymodaq/daq_utils/daq_enums.py +0 -133
  152. pymodaq/daq_utils/daq_utils.py +0 -1402
  153. pymodaq/daq_utils/exceptions.py +0 -71
  154. pymodaq/daq_utils/gui_utils/custom_app.py +0 -103
  155. pymodaq/daq_utils/gui_utils/file_io.py +0 -75
  156. pymodaq/daq_utils/gui_utils/widgets/spinbox.py +0 -9
  157. pymodaq/daq_utils/h5exporter_hyperspy.py +0 -115
  158. pymodaq/daq_utils/h5exporters.py +0 -242
  159. pymodaq/daq_utils/h5modules.py +0 -1559
  160. pymodaq/daq_utils/h5utils.py +0 -241
  161. pymodaq/daq_utils/managers/action_manager.py +0 -236
  162. pymodaq/daq_utils/managers/parameter_manager.py +0 -57
  163. pymodaq/daq_utils/math_utils.py +0 -705
  164. pymodaq/daq_utils/parameter/__init__.py +0 -1
  165. pymodaq/daq_utils/parameter/oldpymodaq_ptypes.py +0 -1626
  166. pymodaq/daq_utils/parameter/pymodaq_ptypes/pixmap.py +0 -85
  167. pymodaq/daq_utils/parameter/utils.py +0 -136
  168. pymodaq/daq_utils/plotting/data_viewers/__init__.py +0 -0
  169. pymodaq/daq_utils/plotting/data_viewers/process_from_QtDesigner_0DViewer_GUI.bat +0 -2
  170. pymodaq/daq_utils/plotting/data_viewers/viewer0D.py +0 -204
  171. pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.py +0 -89
  172. pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.ui +0 -131
  173. pymodaq/daq_utils/plotting/data_viewers/viewer1D.py +0 -781
  174. pymodaq/daq_utils/plotting/data_viewers/viewerND.py +0 -894
  175. pymodaq/daq_utils/plotting/data_viewers/viewerbase.py +0 -64
  176. pymodaq/daq_utils/plotting/items/__init__.py +0 -0
  177. pymodaq/daq_utils/plotting/navigator.py +0 -500
  178. pymodaq/daq_utils/plotting/scan_selector.py +0 -289
  179. pymodaq/daq_utils/plotting/utils/__init__.py +0 -0
  180. pymodaq/daq_utils/plotting/utils/filter.py +0 -236
  181. pymodaq/daq_utils/plotting/viewer0D/__init__.py +0 -0
  182. pymodaq/daq_utils/plotting/viewer0D/viewer0D_main.py +0 -4
  183. pymodaq/daq_utils/plotting/viewer1D/__init__.py +0 -0
  184. pymodaq/daq_utils/plotting/viewer1D/viewer1D_main.py +0 -4
  185. pymodaq/daq_utils/plotting/viewer1D/viewer1Dbasic.py +0 -4
  186. pymodaq/daq_utils/plotting/viewer2D/viewer_2D_basic.py +0 -4
  187. pymodaq/daq_utils/plotting/viewer2D/viewer_2D_main.py +0 -4
  188. pymodaq/daq_utils/plotting/viewerND/__init__.py +0 -0
  189. pymodaq/daq_utils/plotting/viewerND/viewerND_main.py +0 -4
  190. pymodaq/daq_utils/scanner.py +0 -1289
  191. pymodaq/daq_utils/tree_layout/__init__.py +0 -0
  192. pymodaq/daq_viewer/__init__.py +0 -0
  193. pymodaq/daq_viewer/daq_gui_settings.py +0 -237
  194. pymodaq/daq_viewer/daq_gui_settings.ui +0 -441
  195. pymodaq/daq_viewer/daq_viewer_main.py +0 -2225
  196. pymodaq/daq_viewer/process_from_QtDesigner_DAQ_GUI_settings.bat +0 -2
  197. pymodaq/daq_viewer/utility_classes.py +0 -673
  198. pymodaq/examples/logger_image/__init__.py +0 -0
  199. pymodaq/examples/logger_image/logger_displayer.py +0 -121
  200. pymodaq/examples/logger_image/setup.svg +0 -3119
  201. pymodaq/examples/logger_image/setup_svg.py +0 -114
  202. pymodaq/h5browser.py +0 -39
  203. pymodaq/utils/scanner.py +0 -15
  204. pymodaq-3.6.13.dist-info/METADATA +0 -39
  205. pymodaq-3.6.13.dist-info/entry_points.txt +0 -8
  206. pymodaq-3.6.13.dist-info/top_level.txt +0 -1
  207. /pymodaq/{daq_analysis → post_treatment/daq_analysis}/__init__.py +0 -0
  208. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/__init__.py +0 -0
  209. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.py +0 -0
  210. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.ui +0 -0
  211. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -0
  212. /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.odt +0 -0
  213. /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.pdf +0 -0
  214. /pymodaq/{daq_move → utils/db}/__init__.py +0 -0
  215. /pymodaq/{daq_utils → utils/db/db_logger}/__init__.py +0 -0
  216. /pymodaq/{daq_utils → utils}/gui_utils/dock.py +0 -0
  217. /pymodaq/{daq_utils → utils}/gui_utils/list_picker.py +0 -0
  218. /pymodaq/{daq_utils/abstract → utils/managers}/__init__.py +0 -0
  219. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/bool.py +0 -0
  220. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/date.py +0 -0
  221. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/list.py +0 -0
  222. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/numeric.py +0 -0
  223. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/tableview.py +0 -0
  224. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/text.py +0 -0
  225. /pymodaq/{daq_utils/db → utils/plotting}/__init__.py +0 -0
  226. /pymodaq/{daq_utils → utils}/plotting/image_viewer.py +0 -0
  227. /pymodaq/{daq_utils/db/db_logger → utils/plotting/items}/__init__.py +0 -0
  228. /pymodaq/{daq_utils → utils}/plotting/items/crosshair.py +0 -0
  229. /pymodaq/{daq_utils/managers → utils/plotting/utils}/__init__.py +0 -0
  230. /pymodaq/{daq_utils → utils}/qvariant.py +0 -0
  231. /pymodaq/{daq_utils/plotting/viewer2D → utils/scanner/scanners}/__init__.py +0 -0
  232. /pymodaq/{daq_utils/plotting → utils/tree_layout}/__init__.py +0 -0
  233. {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
@@ -1,386 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- Created on Mon March 03 2021
4
- author: Sebastien Weber
5
- """
6
- import numpy as np
7
-
8
-
9
- def random_step(start, stop, step):
10
- tmp = start
11
- out = np.array([tmp])
12
- sign = stop - start
13
- if step == 0:
14
- raise ValueError('step must be strictly positive or negative')
15
- if step > 0 and sign > 0:
16
- while tmp <= stop:
17
- tmp = tmp + (np.random.random() + 0.5) * step
18
- out = np.append(out, tmp)
19
- elif step < 0 and sign < 0:
20
- while tmp >= stop:
21
- tmp = tmp + (np.random.random() + 0.5) * step
22
- out = np.append(out, tmp)
23
- else:
24
- raise ValueError(f'the step value {step} is not of the same sign as stop - start : {sign}')
25
- return out[0:-1]
26
-
27
-
28
- def linspace_this_vect(x, y=None, Npts=None):
29
- """
30
- Given a vector x, it returns a vector xlin where xlin is a
31
- linearised version of x on the same interval and with the same size.
32
- if args is provided it is a y vector and the function returns both xlin
33
- and ylin where ylin is a linear interpolation of y on this new xlin axis
34
-
35
- Parameters
36
- ----------
37
- x : (ndarray)
38
- y : (ndarray) optional
39
- Npts: (int) size of the linear vector (optional)
40
-
41
- Returns
42
- -------
43
- xlin : vector
44
- (ylin : vector) optional if args is provided
45
-
46
- """
47
- if not Npts:
48
- Npts = np.size(x)
49
- xlin = np.linspace(np.min(x), np.max(x), Npts)
50
- if y is not None:
51
- ylin = np.interp(xlin, x, y)
52
- return xlin, ylin
53
- else:
54
- return xlin
55
-
56
-
57
- def find_index(x, threshold):
58
- """
59
- find_index finds the index ix such that x(ix) is the closest from threshold
60
-
61
- Parameters
62
- ----------
63
- x : vector
64
- threshold : list of scalar
65
-
66
- Returns
67
- -------
68
- out : list of 2-tuple containing ix,x[ix]
69
- out=[(ix0,xval0),(ix1,xval1),...]
70
- """
71
-
72
- if np.isscalar(threshold):
73
- threshold = [threshold]
74
- out = []
75
- for value in threshold:
76
- ix = int(np.argmin(np.abs(x - value)))
77
- out.append((ix, x[ix]))
78
- return out
79
-
80
-
81
- def find_rising_edges(x, threshold):
82
- """find_rising_edges finds the index ix such that x(ix) is the closest from threshold and values are increasing
83
-
84
- Parameters
85
- ----------
86
- x : vector
87
- threshold : list of scalar
88
-
89
- Returns
90
- -------
91
- out : list of 2-tuple containing ix,x[ix]
92
- out=[(ix0,xval0),(ix1,xval1),...]
93
-
94
- """
95
- x_shifted = np.concatenate((x[1:], np.array((np.NaN,))))
96
- if np.isscalar(threshold):
97
- threshold = [threshold]
98
- out = []
99
- for value in threshold:
100
- dat = np.bitwise_and(x < value, x_shifted > value)
101
- ix = [ind for ind, flag in enumerate(dat) if flag]
102
- out.append((ix, x[ix]))
103
- return out
104
-
105
-
106
- def crop_vector_to_axis(x, V, xlim):
107
- """crops a vector V with given x axis vector to a given xlim tuple
108
-
109
- Parameters
110
- ----------
111
- x : vector
112
- V : vector
113
- xlim: tuple containing (xmin,xmax)
114
-
115
- Returns
116
- -------
117
- x_c : vector
118
- V_c : vector
119
- """
120
- x1 = find_index(x, xlim[0])[0][0]
121
- x2 = find_index(x, xlim[1])[0][0]
122
- if x2 > x1:
123
- ixx = np.linspace(x1, x2, x2 - x1 + 1, dtype=int);
124
- else:
125
- ixx = np.linspace(x2, x1, x1 - x2 + 1, dtype=int);
126
-
127
- x_c = x[ixx]
128
- V_c = V[ixx]
129
- return x_c, V_c
130
-
131
- def rescale(x, window=[0.0, 1.0]):
132
- """ Rescales a numpy array to the range specified by ``window``.
133
-
134
- Default is [0, 1].
135
- """
136
- maxx = np.max(x)
137
- minx = np.min(x)
138
- return (x - minx) / (maxx - minx) * (window[1] - window[0]) + window[0]
139
-
140
-
141
- def marginals(data, normalize=False, axes=None):
142
- """ Calculates the marginals of the data array.
143
-
144
- axes specifies the axes of the marginals, e.g., the axes on which the
145
- sum is projected.
146
-
147
- If axis is None a list of all marginals is returned.
148
- """
149
- if axes is None:
150
- axes = range(data.ndim)
151
- axes = list(axes)
152
- full_axes = list(range(data.ndim))
153
- m = []
154
- for i in axes:
155
- # for the marginal sum over all axes except the specified one
156
- margin_axes = tuple(j for j in full_axes if j != i)
157
- m.append(np.sum(data, axis=margin_axes))
158
- if normalize:
159
- m = [rescale(mx) for mx in m]
160
- return tuple(m) if len(m) != 1 else m[0]
161
-
162
-
163
- def find(x, condition, n=1):
164
- """ Return the index of the nth element that fulfills the condition.
165
- """
166
- search_n = 1
167
- for i in range(len(x)):
168
- if condition(x[i]):
169
- if search_n == n:
170
- return i
171
- search_n += 1
172
- return -1
173
-
174
-
175
- def arglimit(y, threshold=1e-3, padding=0.0, normalize=True):
176
- """ Returns the first and last index where `y >= threshold * max(abs(y))`.
177
- """
178
- t = np.abs(y)
179
- if normalize:
180
- t = t / np.max(t)
181
-
182
- idx1 = find(t, lambda x: x >= threshold)
183
- if idx1 == -1:
184
- idx1 = 0
185
- idx2 = find(t[::-1], lambda x: x >= threshold)
186
- if idx2 == -1:
187
- idx2 = t.shape[0] - 1
188
- else:
189
- idx2 = t.shape[0] - 1 - idx2
190
-
191
- return (idx1, idx2)
192
-
193
-
194
- def limit(x, y=None, threshold=1e-3, padding=0.25, extend=True):
195
- """ Returns the maximum x-range where the y-values are sufficiently large.
196
-
197
- Parameters
198
- ----------
199
- x : array_like
200
- The x values of the graph.
201
- y : array_like, optional
202
- The y values of the graph. If `None` the maximum range of `x` is
203
- used. That is only useful if `padding > 0`.
204
- threshold : float
205
- The threshold relative to the maximum of `y` of values that should be
206
- included in the bracket.
207
- padding : float
208
- The relative padding on each side in fractions of the bracket size.
209
- extend : bool, optional
210
- Signals if the returned range can be larger than the values in ``x``.
211
- Default is `True`.
212
-
213
- Returns
214
- -------
215
- xl, xr : float
216
- Lowest and biggest value of the range.
217
-
218
- """
219
- if y is None:
220
- x1, x2 = np.min(x), np.max(x)
221
- if not extend:
222
- return (x1, x2)
223
- else:
224
- idx1, idx2 = arglimit(y, threshold=threshold)
225
- x1, x2 = sorted([x[idx1], x[idx2]])
226
-
227
- # calculate the padding
228
- if padding != 0.0:
229
- pad = (x2 - x1) * padding
230
- x1 -= pad
231
- x2 += pad
232
-
233
- if not extend:
234
- x1 = max(x1, np.min(x))
235
- x2 = min(x2, np.max(x))
236
-
237
- return (x1, x2)
238
-
239
-
240
- def crop_array_to_axis(x, y, M, cropbox):
241
- """crops an array M with given cropbox as a tuple (xmin,xmax,ymin,ymax).
242
-
243
- Parameters
244
- ----------
245
- x : vector
246
- y : vector
247
- M : 2D array
248
- cropbox: 4 elements tuple containing (xmin,xmax,ymin,ymax)
249
-
250
- Returns
251
- -------
252
- x_c : croped x vector
253
- y_c : croped y vector
254
- M_c : croped 2D M array
255
-
256
- """
257
- x1 = find_index(x, cropbox[0])[0][0]
258
- x2 = find_index(x, cropbox[1])[0][0]
259
- if x2 > x1:
260
- ixx = np.linspace(x1, x2, x2 - x1 + 1, dtype=int)
261
- else:
262
- ixx = np.linspace(x2, x1, x1 - x2 + 1, dtype=int)
263
-
264
- y1 = find_index(y, cropbox[2])[0][0]
265
- y2 = find_index(y, cropbox[3])[0][0]
266
- if y2 > y1:
267
- iyy = np.linspace(y1, y2, y2 - y1 + 1, dtype=int)
268
- else:
269
- iyy = np.linspace(y2, y1, y1 - y2 + 1, dtype=int)
270
-
271
- x_c = x[ixx]
272
- y_c = y[iyy]
273
-
274
- M_c = M[iyy[0]:iyy[-1] + 1, ixx[0]:ixx[-1] + 1]
275
- return x_c, y_c, M_c
276
-
277
-
278
- def interp1D(x, M, xlin, axis=1):
279
- """
280
- same as numpy interp function but works on 2D array
281
- you have to specify the axis over which to do the interpolation
282
- kwargs refers to the numpy interp kwargs
283
- returns both xlin and the new 2D array Minterp
284
- """
285
- if axis == 0:
286
- Minterp = np.zeros((np.size(xlin), np.size(M, axis=1)))
287
- indexes = np.arange(0, np.size(M, axis=1))
288
- for ind in indexes:
289
- # print(ind)
290
- Minterp[:, ind] = np.interp(xlin, x, M[:, ind])
291
- else:
292
- Minterp = np.zeros((np.size(M, axis=0), np.size(xlin)))
293
- indexes = np.arange(0, np.size(M, axis=0))
294
- for ind in indexes:
295
- Minterp[ind, :] = np.interp(xlin, x, M[ind, :])
296
- return Minterp
297
-
298
-
299
- def linspace_this_image(x, M, axis=1, Npts=None):
300
- """
301
- Given a vector x and a 2D array M, it returns an array vector xlin where xlin is a
302
- linearised version of x on the same interval and with the same size. it returns as well
303
- a 2D array Minterp interpolated on the new xlin vector along the specified axis.
304
-
305
- Parameters
306
- ----------
307
- x : (vector)
308
- M : (2D array)
309
- axis : (int)
310
- Npts: (int) size of the linear vector (optional)
311
-
312
- Returns
313
- -------
314
- xlin : vector
315
- Minterp : 2D array
316
- """
317
- xlin = linspace_this_vect(x, Npts=Npts)
318
- Minterp = interp1D(x, M, xlin, axis=axis)
319
-
320
- return xlin, Minterp
321
-
322
-
323
- def max_ind(x, axis=None):
324
- """returns the max value in a vector or array and its index (in a tuple)
325
-
326
- Parameters
327
- ----------
328
- x : vector
329
-
330
- axis : optional dimension aginst which to normalise
331
-
332
- Returns
333
- -------
334
- ind_max : index of the maximum value
335
-
336
- max_val : maximum value
337
- """
338
- ind_max = np.argmax(x, axis=axis)
339
- max_val = np.max(x, axis=axis)
340
- return ind_max, max_val
341
-
342
-
343
- def min_ind(x, axis=None):
344
- """returns the min value in a vector or array and its index (in flattened array)
345
-
346
- Parameters
347
- ----------
348
- x : vector
349
- axis : optional dimension to check the function
350
-
351
- Returns
352
- -------
353
- ind_min : index of the minimum value
354
- min_val : minimum value
355
- """
356
- ind_min = np.argmin(x, axis=axis)
357
- min_val = np.min(x, axis=axis)
358
- return ind_min, min_val
359
-
360
-
361
- if __name__ == '__main__': # pragma: no cover
362
- from pymodaq.daq_utils import daq_utils as utils
363
- import matplotlib.pyplot as plt
364
-
365
- x = random_step(00, 100, 5)
366
- y = random_step(00, 100, 5)
367
- g2 = utils.gauss2D(x, 35, 15, y, 55, 20, 1)
368
- (xlin, g2_interp) = linspace_this_image(x, g2, axis=1, Npts=100)
369
- (ylin, g2_interp_both) = linspace_this_image(y, g2_interp, axis=0, Npts=100)
370
- plt.figure('gauss2D')
371
- plt.subplot(221)
372
- plt.pcolormesh(x, y, g2)
373
- plt.subplot(222)
374
- plt.pcolormesh(xlin, y, g2_interp)
375
- plt.subplot(223)
376
- plt.pcolormesh(xlin, ylin, g2_interp_both)
377
-
378
- plt.show()
379
-
380
- x_c, y_c, M_c = crop_array_to_axis(x, y, g2, [20, 60, 40, 80])
381
- plt.figure('cropped')
382
- plt.subplot(121)
383
- plt.pcolormesh(x, y, g2)
384
- plt.subplot(122)
385
- plt.pcolormesh(x_c, y_c, M_c)
386
- plt.show()
@@ -1,273 +0,0 @@
1
- import datetime
2
- from pathlib import Path
3
- import toml
4
- from qtpy.QtCore import QObject
5
- from pymodaq.daq_utils.messenger import messagebox
6
- from pyqtgraph.parametertree import Parameter, ParameterTree
7
- from qtpy import QtWidgets, QtCore
8
-
9
-
10
- def getitem_recursive(dic, *args):
11
- args = list(args)
12
- while len(args) > 0:
13
- dic = dic[args.pop(0)]
14
- return dic
15
-
16
-
17
- def get_set_local_dir(basename='pymodaq_local'):
18
- """Defines, creates abd returns a local folder where configurations files will be saved
19
-
20
- Parameters
21
- ----------
22
- basename: (str) how the configuration folder will be named
23
-
24
- Returns
25
- -------
26
- Path: the local path
27
- """
28
- local_path = Path.home().joinpath(basename)
29
-
30
- if not local_path.is_dir(): # pragma: no cover
31
- try:
32
- local_path.mkdir()
33
- except Exception as e:
34
- local_path = Path(__file__).parent.parent.joinpath(basename)
35
- info = f"Cannot create local folder from your **Home** defined location: {Path.home()}," \
36
- f" using PyMoDAQ's folder as local directory: {local_path}"
37
- print(info)
38
- if not local_path.is_dir():
39
- local_path.mkdir()
40
- return local_path
41
-
42
-
43
- def get_set_config_path(config_name='config'):
44
- """Creates a folder in the local config directory to store specific configuration files
45
-
46
- Parameters
47
- ----------
48
- config_name: (str) name of the configuration folder
49
-
50
- Returns
51
- -------
52
-
53
- See Also
54
- --------
55
- get_set_local_dir
56
- """
57
- local_path = get_set_local_dir()
58
- path = local_path.joinpath(config_name)
59
- if not path.is_dir():
60
- path.mkdir() # pragma: no cover
61
- return path
62
-
63
-
64
- def get_set_log_path():
65
- """ creates and return the config folder path for log files
66
- """
67
- return get_set_config_path('log')
68
-
69
-
70
- def get_set_preset_path():
71
- """ creates and return the config folder path for managers files
72
- """
73
- return get_set_config_path('preset_configs')
74
-
75
-
76
- def get_set_batch_path():
77
- """ creates and return the config folder path for managers files
78
- """
79
- return get_set_config_path('batch_configs')
80
-
81
-
82
- def get_set_pid_path():
83
- """ creates and return the config folder path for PID files
84
- """
85
- return get_set_config_path('pid_configs')
86
-
87
-
88
- def get_set_layout_path():
89
- """ creates and return the config folder path for layout files
90
- """
91
- return get_set_config_path('layout_configs')
92
-
93
-
94
- def get_set_remote_path():
95
- """ creates and return the config folder path for remote (shortcuts or joystick) files
96
- """
97
- return get_set_config_path('remote_configs')
98
-
99
-
100
- def get_set_overshoot_path():
101
- """ creates and return the config folder path for overshoot files
102
- """
103
- return get_set_config_path('overshoot_configs')
104
-
105
-
106
- def get_set_roi_path():
107
- """ creates and return the config folder path for managers files
108
- """
109
- return get_set_config_path('roi_configs')
110
-
111
-
112
- def load_config(config_path=None, config_base_path=None):
113
- if not config_path:
114
- config_path = get_set_local_dir().joinpath('config.toml')
115
- if not config_base_path:
116
- config_base = toml.load(Path(__file__).parent.parent.joinpath('resources/config_template.toml'))
117
- else:
118
- config_base = toml.load(config_base_path)
119
- if not config_path.exists(): # copy the template from pymodaq folder and create one in pymodad's local folder
120
- config_path.write_text(toml.dumps(config_base))
121
-
122
- # check if all fields are there
123
- config = toml.load(config_path)
124
- if check_config(config_base, config):
125
- config_path.write_text(toml.dumps(config))
126
- config = config_base
127
- return config
128
-
129
-
130
- class ConfigError(Exception):
131
- pass
132
-
133
-
134
- class Config:
135
- def __init__(self, config_path=None, config_base_path=None):
136
- self._config = load_config(config_path, config_base_path)
137
- self.config_path = config_path
138
- self.config_base_path = config_base_path
139
-
140
- def __call__(self, *args):
141
- try:
142
- ret = getitem_recursive(self._config, *args)
143
- except KeyError as e:
144
- raise ConfigError(f'the path {args} does not exist in your configuration toml file, check '
145
- f'your pymodaq_local folder')
146
- return ret
147
-
148
- def to_dict(self):
149
- return self._config
150
-
151
- def __getitem__(self, item):
152
- """for backcompatibility when it was a dictionnary"""
153
- return self._config[item]
154
-
155
-
156
- def set_config(config_as_dict, config_path=None):
157
- if not config_path:
158
- config_path = get_set_local_dir().joinpath('config.toml')
159
-
160
- config_path.write_text(toml.dumps(config_as_dict))
161
-
162
-
163
- def check_config(config_base, config_local):
164
- status = False
165
- for key in config_base:
166
- if key in config_local:
167
- if isinstance(config_base[key], dict):
168
- status = status or check_config(config_base[key], config_local[key])
169
- else:
170
- config_local[key] = config_base[key]
171
- status = True
172
- return status
173
-
174
-
175
- class TreeFromToml(QObject):
176
- def __init__(self, config=None, conf_path=None, config_base_path=None):
177
- super().__init__()
178
- if config is None:
179
- if conf_path is None:
180
- config_path = get_set_local_dir().joinpath('config.toml')
181
- else:
182
- config_path = conf_path
183
- config = Config(config_path, config_base_path)
184
- self.config_path = config_path
185
- params = [{'title': 'Config path', 'name': 'config_path', 'type': 'str', 'value': str(config.config_path),
186
- 'readonly': True}]
187
- params.extend(self.dict_to_param(config.to_dict()))
188
-
189
- self.settings = Parameter.create(title='settings', name='settings', type='group', children=params)
190
- self.settings_tree = ParameterTree()
191
- self.settings_tree.setParameters(self.settings, showTop=False)
192
-
193
- def show_dialog(self):
194
-
195
- self.dialog = QtWidgets.QDialog()
196
- self.dialog.setWindowTitle('Please enter new configuration values!')
197
- self.dialog.setLayout(QtWidgets.QVBoxLayout())
198
- buttonBox = QtWidgets.QDialogButtonBox(parent=self.dialog)
199
-
200
- buttonBox.addButton('Save', buttonBox.AcceptRole)
201
- buttonBox.accepted.connect(self.dialog.accept)
202
- buttonBox.addButton('Cancel', buttonBox.RejectRole)
203
- buttonBox.rejected.connect(self.dialog.reject)
204
-
205
- self.dialog.layout().addWidget(self.settings_tree)
206
- self.dialog.layout().addWidget(buttonBox)
207
- self.dialog.setWindowTitle('Configuration entries')
208
- res = self.dialog.exec()
209
-
210
- if res == self.dialog.Accepted:
211
- with open(self.config_path, 'w') as f:
212
- config = self.param_to_dict(self.settings)
213
- config.pop('config_path')
214
- toml.dump(config, f)
215
-
216
- @classmethod
217
- def param_to_dict(cls, param):
218
- config = dict()
219
- for child in param.children():
220
- if 'group' in child.opts['type']:
221
- config[child.name()] = cls.param_to_dict(child)
222
- else:
223
- if child.opts['type'] == 'datetime':
224
- config[child.name()] = datetime.fromtimestamp(
225
- child.value().toSecsSinceEpoch()) # convert QDateTime to python datetime
226
- elif child.opts['type'] == 'date':
227
- qdt = QtCore.QDateTime()
228
- qdt.setDate(child.value())
229
- pdt = datetime.fromtimestamp(qdt.toSecsSinceEpoch())
230
- config[child.name()] = pdt.date()
231
- elif child.opts['type'] == 'list':
232
- config[child.name()] = child.opts['limits']
233
- else:
234
- config[child.name()] = child.value()
235
- return config
236
-
237
- @classmethod
238
- def dict_to_param(cls, config):
239
- params = []
240
- for key in config:
241
- if isinstance(config[key], dict):
242
- params.append({'title': f'{key.capitalize()}:', 'name': key, 'type': 'group',
243
- 'children': cls.dict_to_param(config[key]),
244
- 'expanded': 'user' in key.lower() or 'general' in key.lower()})
245
- else:
246
- param = {'title': f'{key.capitalize()}:', 'name': key, 'value': config[key]}
247
- if isinstance(config[key], float):
248
- param['type'] = 'float'
249
- elif isinstance(config[key], bool): # placed before int because a bool is an instance of int
250
- param['type'] = 'bool'
251
- elif isinstance(config[key], int):
252
- param['type'] = 'int'
253
- elif isinstance(config[key], datetime.datetime):
254
- param['type'] = 'datetime'
255
- elif isinstance(config[key], datetime.date):
256
- param['type'] = 'date'
257
- elif isinstance(config[key], str):
258
- param['type'] = 'str'
259
- elif isinstance(config[key], list):
260
- param['type'] = 'list'
261
- param['values'] = config[key]
262
- param['value'] = config[key][0]
263
- param['show_pb'] = True
264
- params.append(param)
265
- return params
266
-
267
-
268
- if __name__ == '__main__':
269
- config = load_config()
270
- config = Config()
271
- config('style', 'darkstyle')
272
- assert config('style', 'darkstyle') == config['style']['darkstyle']
273
-
@@ -1,7 +0,0 @@
1
-
2
- qtbotskip = False
3
-
4
- main_modules_skip = True
5
-
6
-
7
-
@@ -1,9 +0,0 @@
1
- from .daq_utils import set_logger
2
- from .parameter.ioxml import *
3
- from .parameter.pymodaq_ptypes import *
4
- from .parameter.utils import *
5
-
6
- logger = set_logger('custom_paramater', add_to_console=True)
7
- logger.warning('Calling the custom_parameter_module will soon be deprecated!\n'
8
- 'Please use either the ioxml, utils or pymodaq_ptypes submodules from the '
9
- 'pymodaq.daq_utils.parameter module')