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,21 +1,24 @@
1
1
  import logging
2
2
  import datetime
3
+ from typing import List
3
4
 
4
- from pymodaq.daq_utils.config import Config
5
+ from pymodaq.utils.logger import set_logger, get_module_name, get_module_name
6
+ from pymodaq.utils.config import Config
5
7
  from qtpy import QtCore
6
8
  from contextlib import contextmanager
7
9
  from sqlalchemy import create_engine
8
10
  from sqlalchemy.orm import sessionmaker
9
11
  from sqlalchemy_utils import database_exists, create_database
10
- from pymodaq.daq_utils.db.db_logger.db_logger_models import Base, Data0D, Data1D, Data2D, LogInfo, Detector, Configuration
11
- from pymodaq.daq_utils import daq_utils as utils
12
- from pymodaq.daq_utils.gui_utils import dashboard_submodules_params
13
- from pymodaq.daq_utils.messenger import messagebox
14
- from pymodaq.daq_utils.abstract.logger import AbstractLogger
12
+ from pymodaq.utils.db.db_logger.db_logger_models import Base, Data0D, Data1D, Data2D, LogInfo,\
13
+ Configuration, ControlModule
14
+ from pymodaq.utils import daq_utils as utils
15
+ from pymodaq.utils.gui_utils.utils import dashboard_submodules_params
16
+ from pymodaq.utils.messenger import messagebox, deprecation_msg
17
+ from pymodaq.utils.abstract.logger import AbstractLogger
15
18
  from pyqtgraph.parametertree import Parameter, ParameterTree
16
19
 
17
20
 
18
- logger = utils.set_logger(utils.get_module_name(__file__))
21
+ logger = set_logger(get_module_name(__file__))
19
22
  config = Config()
20
23
 
21
24
 
@@ -112,7 +115,7 @@ class DbLogger:
112
115
  if self.engine is not None:
113
116
  Base.metadata.create_all(self.engine)
114
117
 
115
- def get_detectors(self, session):
118
+ def get_detectors(self, session) -> List[str]:
116
119
  """Returns the list of detectors name
117
120
 
118
121
  Parameters
@@ -121,25 +124,51 @@ class DbLogger:
121
124
 
122
125
  Returns
123
126
  -------
124
- list of str
127
+ the list of all created detectors
125
128
  """
126
- return [res[0] for res in session.query(Detector.name)]
129
+ return [res[0] for res in session.query(ControlModule.name)]
130
+
131
+ def get_actuators(self, session) -> List[str]:
132
+ """Returns the list of actuators name
133
+
134
+ Parameters
135
+ ----------
136
+ session: (Session) SQLAlchemy session instance for db transactions
137
+
138
+ Returns
139
+ -------
140
+ the list of all created actuators
141
+ """
142
+ return [res[0] for res in session.query(ControlModule.name)]
127
143
 
128
144
  def add_detectors(self, detectors):
129
145
  """
130
146
  add detectors in the detectors table
131
147
  Parameters
132
148
  ----------
133
- session: (Session) SQLAlchemy session instance for db transactions
134
149
  detectors: (list) list of dict with keys: name and settings_xml
135
150
  """
136
- if not isinstance(detectors, list):
137
- detectors = [detectors]
151
+ self.add_control_modules(detectors, 'DAQ_Viewer')
152
+
153
+ def add_actuators(self, actuators):
154
+ """
155
+ add actuators in the actuators table
156
+ Parameters
157
+ ----------
158
+ actuators: list
159
+ list of dict with keys: name and settings_xml
160
+ """
161
+ self.add_control_modules(actuators, 'DAQ_Move')
162
+
163
+ def add_control_modules(self, modules, module_type='DAQ_Viewer'):
164
+ if not isinstance(modules, list):
165
+ modules = [modules]
138
166
  with self.session_scope() as session:
139
- existing_detectors = [d.name for d in session.query(Detector)]
140
- for det in detectors:
141
- if det['name'] not in existing_detectors:
142
- session.add(Detector(name=det['name'], settings_xml=det['xml_settings']))
167
+ existing_modules = [d.name for d in session.query(ControlModule)]
168
+ for mod in modules:
169
+ if mod['name'] not in existing_modules:
170
+ session.add(ControlModule(name=mod['name'], module_type=module_type,
171
+ settings_xml=mod['xml_settings']))
143
172
 
144
173
  def add_config(self, config_settings):
145
174
  with self.session_scope() as session:
@@ -149,37 +178,44 @@ class DbLogger:
149
178
  with self.session_scope() as session:
150
179
  session.add(LogInfo(log))
151
180
 
152
- def add_datas(self, datas):
181
+ def add_data(self, data):
153
182
  with self.session_scope() as session:
154
- time_stamp = datas['acq_time_s']
155
- detector_name = datas['name']
156
- if session.query(Detector).filter_by(name=detector_name).count() == 0:
157
- # security detector adding in case it hasn't been done previously (and properly)
158
- self.add_detectors(session, dict(name=detector_name))
159
-
160
- det_id = session.query(Detector).filter_by(name=detector_name).one().id # detector names should/are unique
161
-
162
- if 'data0D' in datas:
163
- for channel in datas['data0D']:
164
- session.add(Data0D(timestamp=time_stamp, detector_id=det_id,
165
- channel=f"{datas['data0D'][channel]['name']}:{channel}",
166
- value=datas['data0D'][channel]['data']))
167
-
168
- if 'data1D' in datas:
169
- for channel in datas['data1D']:
170
- session.add(Data1D(timestamp=time_stamp, detector_id=det_id,
171
- channel=f"{datas['data1D'][channel]['name']}:{channel}",
172
- value=datas['data1D'][channel]['data'].tolist()))
173
-
174
- if 'data2D' in datas and self.save2D:
175
- for channel in datas['data2D']:
176
- session.add(Data2D(timestamp=time_stamp, detector_id=det_id,
177
- channel=f"{datas['data2D'][channel]['name']}:{channel}",
178
- value=datas['data2D'][channel]['data'].tolist()))
183
+ time_stamp = data['acq_time_s']
184
+ module_name = data['name']
185
+
186
+ if session.query(ControlModule).filter_by(name=module_name).count() == 0:
187
+ self.add_control_modules(session, dict(name=module_name), data['control_module'])
188
+
189
+ module_id = session.query(ControlModule).filter_by(name=module_name).one().id # detector/actuator names should/are unique
190
+
191
+ if 'data0D' in data:
192
+ for channel in data['data0D']:
193
+ d = data['data0D'][channel]['data']
194
+ if hasattr(d, '__len__'):
195
+ d = float(d[0])
196
+ if data['control_module'] == 'DAQ_Move':
197
+ channel = f"{data['data0D'][channel]['name']}"
198
+ else:
199
+ channel = f"{data['data0D'][channel]['name']}:{channel}"
200
+ session.add(Data0D(timestamp=time_stamp, control_module_id=module_id, channel=channel, value=d))
201
+
202
+ if 'data1D' in data:
203
+ for channel in data['data1D']:
204
+ session.add(Data1D(timestamp=time_stamp, control_module_id=module_id,
205
+ channel=f"{data['data1D'][channel]['name']}:{channel}",
206
+ value=data['data1D'][channel]['data'].tolist()))
207
+
208
+ if 'data2D' in data and self.save2D:
209
+ for channel in data['data2D']:
210
+ session.add(Data2D(timestamp=time_stamp, control_module_id=module_id,
211
+ channel=f"{data['data2D'][channel]['name']}:{channel}",
212
+ value=data['data2D'][channel]['data'].tolist()))
179
213
 
180
214
  # not yet dataND as db should not know where to save these datas
181
215
 
182
216
 
217
+
218
+
183
219
  class DbLoggerGUI(DbLogger, QtCore.QObject):
184
220
  params = [
185
221
  {'title': 'Database:', 'name': 'database_type', 'type': 'list', 'value': 'PostgreSQL',
@@ -276,10 +312,13 @@ class DataBaseLogger(AbstractLogger):
276
312
  def add_detector(self, det_name, settings):
277
313
  self.dblogger.add_detectors([dict(name=det_name, xml_settings=settings)])
278
314
 
279
- def add_datas(self, datas):
280
- self.dblogger.add_datas(datas)
281
- self.settings.child(('N_saved')).setValue(
282
- self.settings.child(('N_saved')).value() + 1)
315
+ def add_actuator(self, act_name, settings):
316
+ self.dblogger.add_actuators([dict(name=act_name, xml_settings=settings)])
317
+
318
+ def add_data(self, data):
319
+ self.dblogger.add_data(data)
320
+ self.settings.child('N_saved').setValue(
321
+ self.settings.child('N_saved').value() + 1)
283
322
 
284
323
  def stop_logger(self):
285
324
  pass
@@ -15,18 +15,39 @@ class Configuration(Base):
15
15
  def __repr__(self):
16
16
  return f"<Config(date='{datetime.datetime.fromtimestamp(self.timestamp).isoformat()}', settings_xml='{self.settings_xml[0:20]}')>"
17
17
 
18
-
19
- class Detector(Base):
20
- __tablename__ = 'detectors'
18
+ # class Actuator(Base):
19
+ # __tablename__ = 'actuators'
20
+ # id = Column(Integer, primary_key=True)
21
+ # name = Column(String(128))
22
+ # settings_xml = Column(String)
23
+ # datas0D = relationship("Data0D", backref='actuators')
24
+ #
25
+ #
26
+ # class Detector(Base):
27
+ # __tablename__ = 'detectors'
28
+ # id = Column(Integer, primary_key=True)
29
+ # name = Column(String(128))
30
+ # settings_xml = Column(String)
31
+ # datas0D = relationship("Data0D", backref='detectors')
32
+ # datas1D = relationship("Data1D", backref='detectors')
33
+ # datas2D = relationship("Data2D", backref='detectors')
34
+ #
35
+ # def __repr__(self):
36
+ # return f"<Detector(name='{self.name}', settings_xml='{self.settings_xml[0:20]}')>"
37
+
38
+
39
+ class ControlModule(Base):
40
+ __tablename__ = 'control_modules'
21
41
  id = Column(Integer, primary_key=True)
22
42
  name = Column(String(128))
43
+ module_type = Column(String(128))
23
44
  settings_xml = Column(String)
24
- datas0D = relationship("Data0D", backref='detectors')
25
- datas1D = relationship("Data1D", backref='detectors')
26
- datas2D = relationship("Data2D", backref='detectors')
45
+ datas0D = relationship("Data0D", backref='control_modules')
46
+ datas1D = relationship("Data1D", backref='control_modules')
47
+ datas2D = relationship("Data2D", backref='control_modules')
27
48
 
28
49
  def __repr__(self):
29
- return f"<Detector(name='{self.name}', settings_xml='{self.settings_xml[0:20]}')>"
50
+ return f"<Control Module {self.type} (name='{self.name}', settings_xml='{self.settings_xml[0:20]}')>"
30
51
 
31
52
 
32
53
  class LogInfo(Base):
@@ -43,7 +64,7 @@ class Data0D(Base):
43
64
 
44
65
  id = Column(Integer, primary_key=True)
45
66
  timestamp = Column(Integer, nullable=False, index=True)
46
- detector_id = Column(Integer, ForeignKey('detectors.id'), index=True)
67
+ control_module_id = Column(Integer, ForeignKey('control_modules.id'), index=True)
47
68
  channel = Column(String(128))
48
69
  value = Column(Float)
49
70
 
@@ -56,7 +77,7 @@ class Data1D(Base):
56
77
 
57
78
  id = Column(Integer, primary_key=True)
58
79
  timestamp = Column(Integer, nullable=False, index=True)
59
- detector_id = Column(Integer, ForeignKey('detectors.id'), index=True)
80
+ control_module_id = Column(Integer, ForeignKey('control_modules.id'), index=True)
60
81
  channel = Column(String(128))
61
82
  value = Column(Array(Float, dimensions=1))
62
83
 
@@ -69,7 +90,7 @@ class Data2D(Base):
69
90
 
70
91
  id = Column(Integer, primary_key=True)
71
92
  timestamp = Column(Integer, nullable=False, index=True)
72
- detector_id = Column(Integer, ForeignKey('detectors.id'), index=True)
93
+ control_module_id = Column(Integer, ForeignKey('control_modules.id'), index=True)
73
94
  channel = Column(String(128))
74
95
  value = Column(Array(Float, dimensions=2))
75
96
 
@@ -1,10 +1,8 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- Created the 11/01/2023
4
-
5
- @author: Sebastien Weber
6
- """
7
1
  from enum import Enum
2
+ from pymodaq.utils.daq_utils import find_index
3
+ from pymodaq.utils.math_utils import my_moment
4
+ import numpy as np
5
+ from scipy.optimize import curve_fit
8
6
  from typing import List, Union
9
7
 
10
8
 
@@ -31,11 +29,15 @@ class BaseEnum(Enum):
31
29
 
32
30
  def enum_checker(enum: BaseEnum, item: Union[BaseEnum, str]):
33
31
  """Check if the item parameter is a valid enum or at least one valid string name of the enum
32
+
34
33
  If a string, transforms it to a valid enum (case not important)
34
+
35
35
  Parameters
36
36
  ----------
37
37
  enum: BaseEnum class or one of its derivated class
38
+
38
39
  item: str or BaseEnum instance
40
+
39
41
  Returns
40
42
  -------
41
43
  BaseEnum class or one of its derivated class
@@ -52,4 +54,7 @@ def enum_checker(enum: BaseEnum, item: Union[BaseEnum, str]):
52
54
  else:
53
55
  raise ValueError(f'{item} is an invalid {enum}. Should be a {enum} enum or '
54
56
  f'a string in {enum.names()}')
55
- return item
57
+ return item
58
+
59
+
60
+
@@ -0,0 +1,37 @@
1
+ class DAQ_ScanException(Exception):
2
+ """Raised when an error occur within the DAQScan"""
3
+ pass
4
+
5
+
6
+
7
+
8
+
9
+ class DetectorError(Exception):
10
+ pass
11
+
12
+
13
+ class ActuatorError(Exception):
14
+ pass
15
+
16
+
17
+ class ViewerError(Exception):
18
+ pass
19
+
20
+
21
+ class ExpectedError(Exception):
22
+ """Raised in the tests made for pymodaq plugins"""
23
+ pass
24
+
25
+
26
+ class Expected_1(ExpectedError):
27
+ """Expected error 1 for pymodaq tests"""
28
+ pass
29
+
30
+
31
+ class Expected_2(ExpectedError):
32
+ """Expected error 2 for pymodaq tests"""
33
+ pass
34
+
35
+
36
+ class Expected_3(ExpectedError):
37
+ """Expected error 3 for pymodaq tests"""
@@ -0,0 +1,82 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created the 04/11/2022
4
+
5
+ @author: Sebastien Weber
6
+ """
7
+ from typing import Callable, Union
8
+ from abc import ABCMeta, abstractmethod
9
+
10
+ from pymodaq.utils.logger import set_logger, get_module_name
11
+
12
+ logger = set_logger(get_module_name(__file__))
13
+
14
+
15
+ class BuilderBase(ABCMeta):
16
+ """Abstract class defining an object/service builder with a callable interface accepting some arguments
17
+
18
+ See https://realpython.com/factory-method-python/ for some details
19
+
20
+ See Also
21
+ --------
22
+ pymodaq.post_treatment.process_1d_to_scalar
23
+ """
24
+ @abstractmethod
25
+ def __call__(self, *args, **kwargs):
26
+ pass
27
+
28
+
29
+ class ObjectFactory(metaclass=ABCMeta):
30
+ """Generic ObjectFactory with a decorator register to add object builders to the factory with a unique key
31
+ identifier
32
+
33
+ See https://realpython.com/factory-method-python/ for some details
34
+
35
+ Examples
36
+ --------
37
+ @ObjectFactory.register('custom')
38
+ def my_custom_builder():
39
+ pass
40
+
41
+ See Also
42
+ --------
43
+ pymodaq.post_treatment.process_1d_to_scalar.Data1DProcessorFactory
44
+ """
45
+ _builders = {}
46
+
47
+ @classmethod
48
+ def register(cls, key: str) -> Callable:
49
+ def inner_wrapper(wrapped_class: Union[BuilderBase, Callable]) -> Callable:
50
+ if cls.__name__ not in cls._builders:
51
+ cls._builders[cls.__name__] = {}
52
+ if key not in cls._builders[cls.__name__]:
53
+ cls._builders[cls.__name__][key] = wrapped_class
54
+ else:
55
+ logger.warning(f'The {cls.__name__}/{key} builder is already registered. Replacing it')
56
+ return wrapped_class
57
+ return inner_wrapper
58
+
59
+ @property
60
+ def builders(self):
61
+ return self._builders
62
+
63
+ def keys_function(self, do_sort=True):
64
+ if do_sort:
65
+ return self.keys
66
+ else:
67
+ return list(self.builders[self.__class__.__name__].keys())
68
+
69
+ @property
70
+ def keys(self):
71
+ return sorted(list(self.builders[self.__class__.__name__].keys()))
72
+
73
+ @classmethod
74
+ def create(cls, key, **kwargs):
75
+ builder = cls._builders[cls.__name__].get(key)
76
+ if not builder:
77
+ raise ValueError(key)
78
+ return builder(**kwargs)
79
+
80
+ @classmethod
81
+ def get_class(cls, key):
82
+ return cls._builders[cls.__name__].get(key)
@@ -3,8 +3,8 @@ from .list_picker import ListPicker
3
3
  from .custom_app import CustomApp
4
4
  from .file_io import select_file
5
5
  from .widgets.table import TableView, TableModel, SpinBoxDelegate, BooleanDelegate
6
- from .widgets.lcd import LCD
7
6
  from .widgets.push import PushButtonIcon, EditPush, EditPushRel, EditPushInfo
8
7
  from .widgets.qled import QLED
9
8
  from .widgets.spinbox import QSpinBox_ro
10
9
 
10
+ from .utils import get_splash_sc
@@ -0,0 +1,129 @@
1
+ from qtpy.QtCore import QObject, QLocale
2
+ from pymodaq.utils.gui_utils.dock import DockArea
3
+ from pymodaq.utils.managers.action_manager import ActionManager
4
+ from pymodaq.utils.managers.parameter_manager import ParameterManager
5
+ from pyqtgraph.dockarea import DockArea
6
+ from qtpy import QtCore, QtWidgets
7
+ from typing import Union
8
+
9
+
10
+ class CustomApp(QObject, ActionManager, ParameterManager):
11
+ """Base Class to ease the implementation of User Interfaces
12
+
13
+ Inherits the MixIns ActionManager and ParameterManager classes. You have to subclass some methods and make
14
+ concrete implementation of a given number of methods:
15
+
16
+ * setup_actions: mandatory, see :class:`pymodaq.utils.managers.action_manager.ActionManager`
17
+ * value_changed: non mandatory, see :class:`pymodaq.utils.managers.parameter_manager.ParameterManager`
18
+ * child_added: non mandatory, see :class:`pymodaq.utils.managers.parameter_manager.ParameterManager`
19
+ * param_deleted: non mandatory, see :class:`pymodaq.utils.managers.parameter_manager.ParameterManager`
20
+ * setup_docks: mandatory
21
+ * setup_menu: non mandatory
22
+ * connect_things: mandatory
23
+
24
+ Parameters
25
+ ----------
26
+ parent: DockArea or QtWidget
27
+ dashboard: DashBoard, optional
28
+
29
+ See Also
30
+ --------
31
+ :class:`pymodaq.utils.managers.action_manager.ActionManager`,
32
+ :class:`pymodaq.utils.managers.parameter_manager.ParameterManager`,
33
+ :class:`pymodaq.utils.managers.modules_manager.ModulesManager`,
34
+ :class:`pymodaq.dashboard.DashBoard`
35
+ """
36
+
37
+ log_signal = QtCore.Signal(str)
38
+ params = []
39
+
40
+ def __init__(self, parent: Union[DockArea, QtWidgets.QWidget], dashboard=None):
41
+ QObject.__init__(self)
42
+ ActionManager.__init__(self)
43
+ ParameterManager.__init__(self)
44
+ QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates))
45
+
46
+ if not isinstance(parent, DockArea):
47
+ if not isinstance(parent, QtWidgets.QWidget):
48
+ raise Exception('no valid parent container, expected a DockArea or a least a QWidget')
49
+
50
+ self.parent = parent
51
+ if isinstance(parent, DockArea):
52
+ self.dockarea: DockArea = parent
53
+ self.mainwindow: QtWidgets.QMainWindow = parent.parent()
54
+ else:
55
+ self.dockarea: DockArea = None
56
+ self.mainwindow: QtWidgets.QMainWindow = None
57
+ self.dashboard = dashboard
58
+
59
+ self.docks = dict([])
60
+ self.statusbar = None
61
+ self._toolbar = QtWidgets.QToolBar()
62
+
63
+ if self.mainwindow is not None:
64
+ self.mainwindow.addToolBar(self._toolbar)
65
+ self.statusbar = self.mainwindow.statusBar()
66
+
67
+ self.set_toolbar(self._toolbar)
68
+
69
+ def setup_ui(self):
70
+ self.setup_docks()
71
+
72
+ self.setup_actions() # see ActionManager MixIn class
73
+
74
+ self.setup_menu()
75
+
76
+ self.connect_things()
77
+
78
+ def setup_docks(self):
79
+ """Mandatory method to be subclassed to setup the docks layout
80
+
81
+ Examples
82
+ --------
83
+ >>>self.docks['ADock'] = gutils.Dock('ADock name')
84
+ >>>self.dockarea.addDock(self.docks['ADock'])
85
+ >>>self.docks['AnotherDock'] = gutils.Dock('AnotherDock name')
86
+ >>>self.dockarea.addDock(self.docks['AnotherDock'''], 'bottom', self.docks['ADock'])
87
+
88
+ See Also
89
+ --------
90
+ pyqtgraph.dockarea.Dock
91
+ """
92
+ raise NotImplementedError
93
+
94
+ def setup_menu(self):
95
+ """Non mandatory method to be subclassed in order to create a menubar
96
+
97
+ create menu for actions contained into the self._actions, for instance:
98
+
99
+ Examples
100
+ --------
101
+ >>>file_menu = self._menubar.addMenu('File')
102
+ >>>self.affect_to('load', file_menu)
103
+ >>>self.affect_to('save', file_menu)
104
+
105
+ >>>file_menu.addSeparator()
106
+ >>>self.affect_to('quit', file_menu)
107
+
108
+ See Also
109
+ --------
110
+ pymodaq.utils.managers.action_manager.ActionManager
111
+ """
112
+ pass
113
+
114
+ def connect_things(self):
115
+ """Connect actions and/or other widgets signal to methods"""
116
+ raise NotImplementedError
117
+
118
+ @property
119
+ def modules_manager(self):
120
+ """useful tool to interact with DAQ_Moves and DAQ_Viewers
121
+
122
+ Will be available if a DashBoard has been set
123
+
124
+ Returns
125
+ -------
126
+ ModulesManager
127
+ """
128
+ if self.dashboard is not None:
129
+ return self.dashboard.modules_manager
@@ -0,0 +1,66 @@
1
+ from pathlib import Path
2
+
3
+ from pymodaq.utils.config import Config
4
+ from qtpy import QtWidgets
5
+
6
+ config = Config()
7
+
8
+
9
+ def select_file(start_path=config('data_saving', 'h5file', 'save_path'), save=True, ext=None, filter=None,
10
+ force_save_extension=False):
11
+ """Opens a selection file popup for loading or saving a file
12
+
13
+ Parameters
14
+ ----------
15
+ start_path: str or Path
16
+ The strating point in the file/folder system to open the popup from
17
+ save: bool
18
+ if True, ask you to enter a filename (with or without extension)
19
+ ext: str
20
+ the extension string, e.g. xml, h5, png ...
21
+ filter: list of string
22
+ list of possible extensions, mostly valid for loading
23
+ force_save_extension: bool
24
+ if True force the extension of the saved file to be set to ext
25
+
26
+ Returns
27
+ -------
28
+ Path: the Path object of the file to save or load
29
+ """
30
+ if ext is None:
31
+ ext = '.h5'
32
+
33
+ if filter is None:
34
+ if not save:
35
+ if not isinstance(ext, list):
36
+ ext = [ext]
37
+ filter = "Data files ("
38
+ for ext_tmp in ext:
39
+ filter += '*.' + ext_tmp + " "
40
+ filter += ")"
41
+
42
+ if start_path is not None:
43
+ if not isinstance(start_path, str):
44
+ start_path = str(start_path)
45
+ if save:
46
+ fname = QtWidgets.QFileDialog.getSaveFileName(None, 'Enter a file name', start_path,
47
+ filter)
48
+ else:
49
+ fname = QtWidgets.QFileDialog.getOpenFileName(None, 'Select a file name', start_path, filter)
50
+
51
+ fname = fname[0]
52
+ if fname != '': # execute if the user didn't cancel the file selection
53
+ fname = Path(fname)
54
+ if save and force_save_extension:
55
+ parent = fname.parent
56
+ filename = fname.stem
57
+ fname = parent.joinpath(filename + "." + ext) # forcing the right extension on the filename
58
+ return fname # fname is a Path object
59
+
60
+
61
+ if __name__ == '__main__':
62
+ import sys
63
+ app = QtWidgets.QApplication(sys.argv)
64
+ file = select_file(save=True, filter="Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)")
65
+ print(file)
66
+ sys.exit(app.exec_())
@@ -1,7 +1,7 @@
1
1
  import pickle
2
2
 
3
- from pymodaq.daq_utils import config as config_mod
4
- from pymodaq.daq_utils.gui_utils.file_io import select_file
3
+ from pymodaq.utils import config as config_mod
4
+ from pymodaq.utils.gui_utils.file_io import select_file
5
5
 
6
6
 
7
7
  def load_layout_state(dockarea, file=None):