pymodaq 3.6.12__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.12.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
  139. {pymodaq-3.6.12.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 -671
  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.12.dist-info/METADATA +0 -39
  205. pymodaq-3.6.12.dist-info/entry_points.txt +0 -8
  206. pymodaq-3.6.12.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.12.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
@@ -3,8 +3,8 @@ from qtpy import QtWidgets
3
3
  from qtpy.QtCore import QDateTime, Signal, QPointF, QObject
4
4
  import numpy as np
5
5
  import pyqtgraph as pg
6
- from pymodaq.daq_utils.plotting.data_viewers.viewer2D_basic import ImageWidget
7
- from pymodaq.daq_utils.managers.roi_manager import ROIBrushable
6
+ from pymodaq.utils.plotting.widgets.image import ImageWidget
7
+ from pymodaq.utils.managers.roi_manager import ROIBrushable
8
8
 
9
9
  from pyqtgraph.graphicsItems.GradientEditorItem import Gradients
10
10
 
@@ -1,5 +1,7 @@
1
1
  import pyqtgraph as pg
2
- from pymodaq.daq_utils import daq_utils as utils
2
+
3
+ from pymodaq.utils.data import Axis
4
+ from pymodaq.utils import daq_utils as utils
3
5
 
4
6
  AXIS_POSITIONS = ['top', 'bottom', 'right', 'left']
5
7
 
@@ -31,7 +33,7 @@ class AxisItem_Scaled(pg.AxisItem):
31
33
  def axis_data(self, Npts):
32
34
  return utils.linspace_step_N(self.axis_offset, self.axis_scaling, Npts)
33
35
 
34
- def set_scaling_and_label(self, axis_info: utils.ScaledAxis):
36
+ def set_scaling_and_label(self, axis_info: Axis):
35
37
  self.setLabel(axis_info.label, axis_info.units)
36
38
  self.axis_offset = axis_info.offset
37
39
  self.axis_scaling = axis_info.scaling
@@ -2,7 +2,7 @@ import collections
2
2
 
3
3
  import numpy as np
4
4
  import pyqtgraph as pg
5
- from pymodaq.daq_utils.plotting.utils.plot_utils import makeAlphaTriangles, makePolygons
5
+ from pymodaq.utils.plotting.utils.plot_utils import makeAlphaTriangles, makePolygons
6
6
  from pyqtgraph import debug as debug, Point, functions as fn
7
7
  from qtpy import QtCore, QtGui
8
8
 
@@ -46,11 +46,11 @@ class UniformImageItem(PymodaqImage):
46
46
  """
47
47
  return self.image[int(xy[1]), int(xy[0])]
48
48
 
49
- def setRect(self, rect):
50
- """Scale and translate the image to fit within rect (must be a QRect or QRectF)."""
51
- self.resetTransform()
52
- self.translate(rect.left(), rect.top())
53
- self.scale(rect.width() / self.width(), rect.height() / self.height())
49
+ # def setRect(self, rect):
50
+ # """Scale and translate the image to fit within rect (must be a QRect or QRectF)."""
51
+ # self.resetTransform()
52
+ # self._dataTransform.translate(rect.left(), rect.top())
53
+ # self._dataTransform.scale(rect.width() / self.width(), rect.height() / self.height())
54
54
 
55
55
 
56
56
  class SpreadImageItem(PymodaqImage):
@@ -269,6 +269,8 @@ class SpreadImageItem(PymodaqImage):
269
269
  -------
270
270
  ndarray: barycenter coordinates and triangles data values
271
271
  """
272
+ if self.triangulation is None:
273
+ self.render()
272
274
  centroids = self.compute_centroids()
273
275
  points_to_test = centroids.copy()
274
276
  if axis == 'x':
@@ -0,0 +1,355 @@
1
+ from pymodaq.utils.logger import set_logger, get_module_name, get_module_name
2
+ from pymodaq.utils.gui_utils.file_io import select_file
3
+ from qtpy import QtGui, QtWidgets, QtCore
4
+ from qtpy.QtCore import Qt, QObject, Slot, Signal
5
+
6
+ import sys
7
+ import os
8
+ import numpy as np
9
+ import tables
10
+
11
+ from pymodaq.utils.data import DataToExport, DataFromPlugins, DataDim, enum_checker, DataWithAxes
12
+ from pymodaq.utils.h5modules.data_saving import DataLoader
13
+ from pymodaq.utils.managers.parameter_manager import ParameterManager
14
+ from pymodaq.utils.managers.action_manager import ActionManager
15
+ from pymodaq.utils.plotting.data_viewers.viewer2D_basic import Viewer2DBasic
16
+ from pymodaq.utils.plotting.items.image import UniformImageItem, SpreadImageItem
17
+ from pymodaq.utils import daq_utils as utils
18
+ from pymodaq.utils.h5modules.browsing import browse_data, H5BrowserUtil
19
+ from pymodaq.utils.h5modules.saving import H5Saver
20
+ from pymodaq.utils import gui_utils as gutils
21
+ from pymodaq.utils.parameter.pymodaq_ptypes.pixmap import PixmapCheckData
22
+
23
+ from pymodaq.utils.config import get_set_local_dir, Config
24
+
25
+ local_path = get_set_local_dir()
26
+ navigator_path = os.path.join(local_path, 'navigator_temp_files')
27
+ if not os.path.isdir(navigator_path):
28
+ os.makedirs(navigator_path)
29
+
30
+ logger = set_logger(get_module_name(__file__))
31
+
32
+ Ntick = 128
33
+ colors_red = np.array([(int(r), 0, 0) for r in np.linspace(0, 255, Ntick)])
34
+ colors_green = np.array([(0, int(g), 0) for g in np.linspace(0, 255, Ntick)])
35
+ colors_blue = np.array([(0, 0, int(b)) for b in np.linspace(0, 255, Ntick)])
36
+ config = Config()
37
+
38
+
39
+ class Navigator(ParameterManager, ActionManager, QObject):
40
+
41
+ settings_name = 'navigator_settings'
42
+ log_signal = Signal(str)
43
+ sig_double_clicked = Signal(float, float)
44
+ params = [
45
+ {'title': 'Settings', 'name': 'settings', 'type': 'group', 'children': [
46
+ {'title': 'Load h5:', 'name': 'Load h5', 'type': 'action'},
47
+ {'title': 'h5 path:', 'name': 'filepath', 'type': 'str', 'value': '', 'readonly': True},
48
+ {'title': 'Load Image:', 'name': 'Load Image', 'type': 'action'},
49
+ {'title': 'Image path:', 'name': 'imagepath', 'type': 'str', 'value': '', 'readonly': True},
50
+ ]},
51
+ {'title': 'Image', 'name': 'image', 'type': 'pixmap_check'},
52
+ {'title': 'Overlays', 'name': 'overlays', 'type': 'group', 'children': []},
53
+ ]
54
+
55
+ def __init__(self, parent=None, h5file_path=None):
56
+ QObject.__init__(self)
57
+ ParameterManager.__init__(self)
58
+ ActionManager.__init__(self, toolbar=QtWidgets.QToolBar())
59
+ if parent is None:
60
+ parent = QtWidgets.QWidget()
61
+ self.parent = parent
62
+ self.title = 'Navigator'
63
+
64
+ self.status_time = 1000
65
+
66
+ self._h5saver = H5Saver()
67
+ self.dataloader = DataLoader(self._h5saver)
68
+
69
+ self.h5file_path = h5file_path
70
+ self.h5saver_image = H5Saver()
71
+
72
+ self.viewer: Viewer2DBasic = None
73
+
74
+ self.x_range = []
75
+ self.y_range = []
76
+
77
+ self.next_scan_index = 0
78
+
79
+ self.overlays = [] # %list of imageItem items displaying 2D scans info
80
+
81
+ # self.h5module = H5BrowserUtil()
82
+
83
+ self.setup_actions()
84
+ self.setup_ui()
85
+ self.connect_things()
86
+ self.set_aspect_ratio()
87
+
88
+ if h5file_path is not None:
89
+ self.h5saver.open_file(h5file_path, 'a')
90
+ self.settings.child('settings', 'filepath').setValue(h5file_path)
91
+ self.settings.child('settings', 'Load h5').hide()
92
+ self.list_2D_scans()
93
+ # self.show_overlay()
94
+
95
+ @property
96
+ def h5saver(self):
97
+ return self._h5saver
98
+
99
+ @h5saver.setter
100
+ def h5saver(self, h5saver: H5Saver):
101
+ self._h5saver = h5saver
102
+ self.dataloader = DataLoader(h5saver)
103
+
104
+ def setup_actions(self):
105
+
106
+ self.add_action('load_scan', 'Load Scan file', 'NewLayer', 'Load scan file (.h5)')
107
+ self.add_action('load_image', 'Load Image File', 'Open_File_32', 'Load image file (.h5)')
108
+ self.add_action('ratio', 'Viewbox Aspect Ratio', 'Zoom_1_1', 'Set viewbox aspect ratio to 1', checkable=True)
109
+ self.add_action('move_at', 'Move at DoubleClicked', 'move_contour',
110
+ 'When selected, double clicking on viewbox will move DAQ_Move modules',
111
+ checkable=True)
112
+ self.add_action('select_all', 'Select All', 'select_all2', 'Select (show) all 2D scans on the viewer')
113
+ self.add_action('select_none', 'Select None', 'select_none', 'Unselect (hide) all 2D scans on the viewer')
114
+ self.add_action('histogram', 'Show Histograms', 'Histogram', 'Show (hide) histograms', checkable=True)
115
+
116
+ def connect_things(self):
117
+ self.connect_action('load_scan', self.load_data)
118
+ self.connect_action('load_image', self.load_image)
119
+ self.connect_action('ratio', self.set_aspect_ratio)
120
+ self.connect_action('select_all', self.show_all)
121
+ self.connect_action('select_none', self.show_none)
122
+ self.connect_action('histogram', self.show_histo)
123
+
124
+ self.viewer.sig_double_clicked.connect(self.move_at)
125
+ self.settings.child('settings', 'Load h5').sigActivated.connect(self.load_data)
126
+ self.settings.child('settings', 'Load Image').sigActivated.connect(self.load_image)
127
+
128
+ @Slot(float, float)
129
+ def move_at(self, posx, posy):
130
+ if self.is_action_checked('move_at'):
131
+ self.sig_double_clicked.emit(posx, posy)
132
+
133
+ def show_histo(self):
134
+ self.viewer.histo_widget.setVisible(self.is_action_checked('histogram'))
135
+
136
+ def show_all(self):
137
+ self.show_scans()
138
+
139
+ def show_none(self):
140
+ self.show_scans(False)
141
+
142
+ def show_scans(self, show=True):
143
+ for child in self.settings.child('overlays'):
144
+ val = child.value()
145
+ val.checked = show
146
+ child.setValue(val)
147
+ child.sigValueChanged.emit(child, val)
148
+
149
+ def get_data_from_scan_name(self, scan_name: str) -> DataToExport:
150
+ _data = DataToExport('All')
151
+ self.dataloader.load_all(f'/RawData/{scan_name}', _data)
152
+ data_2D = _data.get_data_from_Naxes(2)
153
+ for dat in data_2D: # convert DataWithAxes DataND to Data2D
154
+ dat.nav_indexes = ()
155
+ return data_2D
156
+
157
+ def set_axes(self, dwa: DataWithAxes):
158
+ x_axis = dwa.get_axis_from_index(0)[0]
159
+ y_axis = dwa.get_axis_from_index(1)[0]
160
+
161
+ self.viewer.scaled_xaxis.axis_label = x_axis.label
162
+ self.viewer.scaled_xaxis.axis_units = x_axis.units
163
+
164
+ self.viewer.scaled_yaxis.axis_label = y_axis.label
165
+ self.viewer.scaled_yaxis.axis_units = y_axis.units
166
+
167
+ def list_2D_scans(self):
168
+ try:
169
+ scans = self.h5saver.get_scan_groups()
170
+
171
+ params = []
172
+ for child in self.settings.child('overlays').children():
173
+ self.settings.child('overlays').removeChild(child)
174
+ ind_overlay = 0
175
+ axes_init = False
176
+ for scan in scans:
177
+ data_2D = self.get_data_from_scan_name(scan.name)
178
+ for _dat in data_2D:
179
+ if not axes_init:
180
+ self.set_axes(_dat)
181
+ axes_init = True
182
+ params.append({'name': f'Overlay{ind_overlay:03.0f}', 'type': 'pixmap_check',
183
+ 'value': PixmapCheckData(data=_dat[0], checked=False, path=_dat.path,
184
+ info=f'{scan.name}/{_dat.get_full_name()}')})
185
+ ind_overlay += 1
186
+ self.settings.child('overlays').addChildren(params)
187
+
188
+ for child in self.settings.child('overlays').children():
189
+ val = child.value()
190
+ val.checked = True
191
+ child.setValue(val)
192
+ child.sigValueChanged.emit(child, child.value())
193
+
194
+ except Exception as e:
195
+ logger.exception(str(e))
196
+
197
+ def load_image(self):
198
+ data, fname, node_path = browse_data(ret_all=True)
199
+
200
+ self.h5saver_image = H5Saver()
201
+ self.h5saver_image.open_file(fname, 'r')
202
+
203
+ self.settings.child('settings', 'imagepath').setValue(fname)
204
+ self.settings.child('image').setValue(PixmapCheckData(data=data[0], checked=True, path=data.path))
205
+
206
+ self.settings.child('image').sigValueChanged.emit(
207
+ self.settings.child('image'),
208
+ self.settings.child('image').value())
209
+
210
+ def load_data(self):
211
+ self.h5file_path = str(select_file(start_path=config('data_saving', 'h5file', 'save_path'),
212
+ save=False, ext='h5'))
213
+ if self.h5file_path != '':
214
+ self.settings.child('settings', 'filepath').setValue(self.h5file_path)
215
+ if self.h5saver is not None:
216
+ if self.h5saver.isopen():
217
+ self.h5saver.close_file()
218
+ self.h5saver.open_file(self.h5file_path, 'a')
219
+ self.list_2D_scans()
220
+
221
+ def set_aspect_ratio(self):
222
+ self.viewer.set_aspect_ratio(self.is_action_checked('ratio'))
223
+
224
+ def add_image_data(self, dwa: DataWithAxes):
225
+ ims = []
226
+ histograms = self.viewer.histograms
227
+ for ind, data in enumerate(dwa):
228
+ if ind > 2:
229
+ break
230
+ if dwa.distribution.name == 'spread':
231
+ im = SpreadImageItem()
232
+ else:
233
+ im = UniformImageItem()
234
+ ims.append(im)
235
+
236
+ im.setOpacity(1)
237
+ self.viewer.add_image_item(im, histogram=histograms[ind])
238
+ im.setCompositionMode(QtGui.QPainter.CompositionMode_Plus)
239
+
240
+ if dwa.distribution.name == 'uniform':
241
+ x_axis = dwa.get_axis_from_index(1)[0].get_data()
242
+ y_axis = dwa.get_axis_from_index(0)[0].get_data()
243
+
244
+ rect = QtCore.QRectF(np.min(y_axis), np.min(x_axis),
245
+ (np.max(y_axis) - np.min(y_axis)),
246
+ (np.max(x_axis) - np.min(x_axis)))
247
+
248
+ im.setImage(data)
249
+ im.setOpts(rect=rect)
250
+ else:
251
+ y_axis, x_axis = dwa.get_axis_from_index(0)
252
+ im.setImage(np.vstack((x_axis, y_axis, dwa.data[0])).T)
253
+ histograms[ind].setImageItem(im)
254
+ return ims
255
+
256
+ def remove_image_data(self, param):
257
+ for overlay in self.overlays[:]:
258
+ if param.name() in overlay['name']:
259
+ ind = self.overlays.index(overlay)
260
+ for image in overlay['images']:
261
+ self.viewer.plotitem.removeItem(image)
262
+ self.overlays.pop(ind)
263
+
264
+ def value_changed(self, param):
265
+
266
+ if param.parent().name() == 'overlays':
267
+ data: PixmapCheckData = param.value()
268
+ if data.checked:
269
+ dwa = self.dataloader.load_data(data.path, load_all=True)
270
+ ims = self.add_image_data(dwa)
271
+ self.overlays.append(dict(name=f'{param.name()}_{0}', images=ims))
272
+
273
+ else:
274
+ self.remove_image_data(param)
275
+ elif param.name() == 'image':
276
+ data: PixmapCheckData = param.value()
277
+ if data.checked:
278
+ dataloader = DataLoader(self.h5saver_image)
279
+ dwa = dataloader.load_data(data.path)
280
+ ims = self.add_image_data(dwa)
281
+ self.overlays.append(dict(name='{:s}_{:03d}'.format(param.name(), 0), images=ims))
282
+ else:
283
+ self.remove_image_data(param)
284
+
285
+ def param_deleted(self, param):
286
+ self.remove_image_data(param)
287
+
288
+ def setup_ui(self):
289
+ layout = QtWidgets.QVBoxLayout()
290
+
291
+ self.parent.setLayout(layout)
292
+ self.parent.layout().addWidget(self.toolbar)
293
+ sett_widget = QtWidgets.QWidget()
294
+ self.sett_layout = QtWidgets.QHBoxLayout()
295
+ sett_widget.setLayout(self.sett_layout)
296
+
297
+ layout.addWidget(self.toolbar)
298
+
299
+ splitter = QtWidgets.QSplitter(Qt.Horizontal)
300
+ layout.addWidget(splitter)
301
+
302
+ # set viewer area
303
+ widg = QtWidgets.QWidget()
304
+ self.viewer = Viewer2DBasic(widg)
305
+ self.viewer.histogram_red.setVisible(True)
306
+ self.viewer.histogram_green.setVisible(True)
307
+ self.viewer.histogram_blue.setVisible(True)
308
+ self.viewer.histogram_adaptive.setVisible(False)
309
+
310
+ self.statusbar = QtWidgets.QStatusBar()
311
+ self.statusbar.setMaximumHeight(25)
312
+ layout.addWidget(self.statusbar)
313
+ self.log_message = QtWidgets.QLabel('Initializing')
314
+ self.statusbar.addPermanentWidget(self.log_message)
315
+
316
+ self.sett_layout.addWidget(self.settings_tree)
317
+ splitter.addWidget(sett_widget)
318
+ splitter.addWidget(self.viewer.parent)
319
+
320
+ def update_h5file(self, h5file):
321
+ if self.h5saver is not None:
322
+ self.h5saver.h5file = h5file
323
+ self.dataloader = DataLoader(self.h5saver)
324
+ self.list_2D_scans()
325
+
326
+ def update_status(self, txt, status_time=0, log_type=None):
327
+ """
328
+ Show the txt message in the status bar with a delay of status_time ms.
329
+
330
+ =============== =========== =======================
331
+ **Parameters** **Type** **Description**
332
+ *txt* string The message to show
333
+ *status_time* int the delay of showing
334
+ *log_type* string the type of the log
335
+ =============== =========== =======================
336
+ """
337
+ try:
338
+ self.ui.statusbar.showMessage(txt, status_time)
339
+ logger.info(txt)
340
+ except Exception as e:
341
+ logger.exception(str(e))
342
+
343
+
344
+ def main():
345
+ app = QtWidgets.QApplication(sys.argv)
346
+ widg = QtWidgets.QWidget()
347
+ prog = Navigator(widg)#, h5file_path=r'C:\Data\2023\20230320\Dataset_20230320_001.h5')
348
+
349
+ widg.show()
350
+ prog.list_2D_scans()
351
+ sys.exit(app.exec_())
352
+
353
+
354
+ if __name__ == '__main__':
355
+ main()