pymodaq 5.1.6__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.
Files changed (154) hide show
  1. pymodaq/__init__.py +98 -0
  2. pymodaq/control_modules/__init__.py +1 -0
  3. pymodaq/control_modules/daq_move.py +1238 -0
  4. pymodaq/control_modules/daq_move_ui/__init__.py +0 -0
  5. pymodaq/control_modules/daq_move_ui/factory.py +48 -0
  6. pymodaq/control_modules/daq_move_ui/ui_base.py +359 -0
  7. pymodaq/control_modules/daq_move_ui/uis/__init__.py +0 -0
  8. pymodaq/control_modules/daq_move_ui/uis/binary.py +139 -0
  9. pymodaq/control_modules/daq_move_ui/uis/original.py +120 -0
  10. pymodaq/control_modules/daq_move_ui/uis/relative.py +124 -0
  11. pymodaq/control_modules/daq_move_ui/uis/simple.py +126 -0
  12. pymodaq/control_modules/daq_viewer.py +1517 -0
  13. pymodaq/control_modules/daq_viewer_ui.py +407 -0
  14. pymodaq/control_modules/mocks.py +57 -0
  15. pymodaq/control_modules/move_utility_classes.py +1141 -0
  16. pymodaq/control_modules/thread_commands.py +137 -0
  17. pymodaq/control_modules/ui_utils.py +72 -0
  18. pymodaq/control_modules/utils.py +591 -0
  19. pymodaq/control_modules/viewer_utility_classes.py +670 -0
  20. pymodaq/daq_utils/__init__.py +0 -0
  21. pymodaq/daq_utils/daq_utils.py +6 -0
  22. pymodaq/dashboard.py +2396 -0
  23. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.aliases +3 -0
  24. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvlps +3 -0
  25. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvproj +32 -0
  26. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.vi +0 -0
  27. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_1Dgaussian.vi +0 -0
  28. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_2Dgaussian.vi +0 -0
  29. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_cmd.vi +0 -0
  30. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_float.vi +0 -0
  31. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_int.vi +0 -0
  32. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_data.vi +0 -0
  33. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_int.vi +0 -0
  34. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_scalar.vi +0 -0
  35. pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_string.vi +0 -0
  36. pymodaq/examples/Labview_TCP_Client/client_state.ctl +0 -0
  37. pymodaq/examples/Labview_TCP_Client/cmd_types.ctl +0 -0
  38. pymodaq/examples/__init__.py +0 -0
  39. pymodaq/examples/function_plotter.py +160 -0
  40. pymodaq/examples/nonlinearscanner.py +126 -0
  41. pymodaq/examples/qt_less_standalone_module.py +165 -0
  42. pymodaq/examples/tcp_client.py +97 -0
  43. pymodaq/extensions/__init__.py +25 -0
  44. pymodaq/extensions/adaptive/__init__.py +2 -0
  45. pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
  46. pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
  47. pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
  48. pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
  49. pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
  50. pymodaq/extensions/adaptive/utils.py +123 -0
  51. pymodaq/extensions/bayesian/__init__.py +2 -0
  52. pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
  53. pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
  54. pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
  55. pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
  56. pymodaq/extensions/bayesian/utils.py +180 -0
  57. pymodaq/extensions/console.py +73 -0
  58. pymodaq/extensions/daq_logger/__init__.py +1 -0
  59. pymodaq/extensions/daq_logger/abstract.py +52 -0
  60. pymodaq/extensions/daq_logger/daq_logger.py +519 -0
  61. pymodaq/extensions/daq_logger/db/__init__.py +0 -0
  62. pymodaq/extensions/daq_logger/db/db_logger.py +300 -0
  63. pymodaq/extensions/daq_logger/db/db_logger_models.py +100 -0
  64. pymodaq/extensions/daq_logger/h5logging.py +84 -0
  65. pymodaq/extensions/daq_scan.py +1218 -0
  66. pymodaq/extensions/daq_scan_ui.py +241 -0
  67. pymodaq/extensions/data_mixer/__init__.py +0 -0
  68. pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
  69. pymodaq/extensions/data_mixer/data_mixer.py +262 -0
  70. pymodaq/extensions/data_mixer/model.py +108 -0
  71. pymodaq/extensions/data_mixer/models/__init__.py +0 -0
  72. pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
  73. pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
  74. pymodaq/extensions/data_mixer/parser.py +53 -0
  75. pymodaq/extensions/data_mixer/utils.py +23 -0
  76. pymodaq/extensions/h5browser.py +9 -0
  77. pymodaq/extensions/optimizers_base/__init__.py +0 -0
  78. pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
  79. pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
  80. pymodaq/extensions/optimizers_base/utils.py +427 -0
  81. pymodaq/extensions/pid/__init__.py +16 -0
  82. pymodaq/extensions/pid/actuator_controller.py +14 -0
  83. pymodaq/extensions/pid/daq_move_PID.py +154 -0
  84. pymodaq/extensions/pid/pid_controller.py +1016 -0
  85. pymodaq/extensions/pid/utils.py +189 -0
  86. pymodaq/extensions/utils.py +111 -0
  87. pymodaq/icon.ico +0 -0
  88. pymodaq/post_treatment/__init__.py +6 -0
  89. pymodaq/post_treatment/load_and_plot.py +352 -0
  90. pymodaq/resources/__init__.py +0 -0
  91. pymodaq/resources/config_template.toml +57 -0
  92. pymodaq/resources/preset_default.xml +1 -0
  93. pymodaq/resources/setup_plugin.py +73 -0
  94. pymodaq/splash.png +0 -0
  95. pymodaq/utils/__init__.py +0 -0
  96. pymodaq/utils/array_manipulation.py +6 -0
  97. pymodaq/utils/calibration_camera.py +180 -0
  98. pymodaq/utils/chrono_timer.py +203 -0
  99. pymodaq/utils/config.py +53 -0
  100. pymodaq/utils/conftests.py +5 -0
  101. pymodaq/utils/daq_utils.py +158 -0
  102. pymodaq/utils/data.py +128 -0
  103. pymodaq/utils/enums.py +6 -0
  104. pymodaq/utils/exceptions.py +38 -0
  105. pymodaq/utils/gui_utils/__init__.py +10 -0
  106. pymodaq/utils/gui_utils/loader_utils.py +75 -0
  107. pymodaq/utils/gui_utils/utils.py +18 -0
  108. pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
  109. pymodaq/utils/h5modules/__init__.py +2 -0
  110. pymodaq/utils/h5modules/module_saving.py +526 -0
  111. pymodaq/utils/leco/__init__.py +25 -0
  112. pymodaq/utils/leco/daq_move_LECODirector.py +217 -0
  113. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +163 -0
  114. pymodaq/utils/leco/director_utils.py +74 -0
  115. pymodaq/utils/leco/leco_director.py +166 -0
  116. pymodaq/utils/leco/pymodaq_listener.py +364 -0
  117. pymodaq/utils/leco/rpc_method_definitions.py +43 -0
  118. pymodaq/utils/leco/utils.py +74 -0
  119. pymodaq/utils/logger.py +6 -0
  120. pymodaq/utils/managers/__init__.py +0 -0
  121. pymodaq/utils/managers/batchscan_manager.py +346 -0
  122. pymodaq/utils/managers/modules_manager.py +589 -0
  123. pymodaq/utils/managers/overshoot_manager.py +242 -0
  124. pymodaq/utils/managers/preset_manager.py +229 -0
  125. pymodaq/utils/managers/preset_manager_utils.py +262 -0
  126. pymodaq/utils/managers/remote_manager.py +484 -0
  127. pymodaq/utils/math_utils.py +6 -0
  128. pymodaq/utils/messenger.py +6 -0
  129. pymodaq/utils/parameter/__init__.py +10 -0
  130. pymodaq/utils/parameter/utils.py +6 -0
  131. pymodaq/utils/scanner/__init__.py +5 -0
  132. pymodaq/utils/scanner/scan_config.py +16 -0
  133. pymodaq/utils/scanner/scan_factory.py +259 -0
  134. pymodaq/utils/scanner/scan_selector.py +477 -0
  135. pymodaq/utils/scanner/scanner.py +324 -0
  136. pymodaq/utils/scanner/scanners/_1d_scanners.py +174 -0
  137. pymodaq/utils/scanner/scanners/_2d_scanners.py +299 -0
  138. pymodaq/utils/scanner/scanners/__init__.py +1 -0
  139. pymodaq/utils/scanner/scanners/sequential.py +224 -0
  140. pymodaq/utils/scanner/scanners/tabular.py +319 -0
  141. pymodaq/utils/scanner/utils.py +110 -0
  142. pymodaq/utils/svg/__init__.py +6 -0
  143. pymodaq/utils/svg/svg_renderer.py +20 -0
  144. pymodaq/utils/svg/svg_view.py +35 -0
  145. pymodaq/utils/svg/svg_viewer2D.py +50 -0
  146. pymodaq/utils/tcp_ip/__init__.py +6 -0
  147. pymodaq/utils/tcp_ip/mysocket.py +12 -0
  148. pymodaq/utils/tcp_ip/serializer.py +13 -0
  149. pymodaq/utils/tcp_ip/tcp_server_client.py +772 -0
  150. pymodaq-5.1.6.dist-info/METADATA +238 -0
  151. pymodaq-5.1.6.dist-info/RECORD +154 -0
  152. pymodaq-5.1.6.dist-info/WHEEL +4 -0
  153. pymodaq-5.1.6.dist-info/entry_points.txt +7 -0
  154. pymodaq-5.1.6.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,242 @@
1
+ from qtpy import QtWidgets
2
+ from qtpy.QtWidgets import QMessageBox, QDialogButtonBox, QDialog
3
+ import sys
4
+ import os
5
+
6
+ from pymodaq_gui.parameter import ioxml, Parameter, ParameterTree
7
+ from pymodaq_gui.parameter.pymodaq_ptypes import registerParameterType, GroupParameter
8
+ from pymodaq_gui.utils import select_file
9
+
10
+ # check if overshoot_configurations directory exists on the drive
11
+ from pymodaq.utils.config import get_set_overshoot_path
12
+
13
+ overshoot_path = get_set_overshoot_path()
14
+
15
+
16
+ class PresetScalableGroupMove(GroupParameter):
17
+ """
18
+ |
19
+
20
+ ================ =============
21
+ **Attributes** **Type**
22
+ *opts* dictionnary
23
+ ================ =============
24
+
25
+ See Also
26
+ --------
27
+ hardware.DAQ_Move_Stage_type
28
+ """
29
+
30
+ def __init__(self, **opts):
31
+ opts['type'] = 'groupmoveover'
32
+ opts['addText'] = "Add"
33
+ opts['addList'] = opts['movelist']
34
+ super().__init__(**opts)
35
+
36
+ def addNew(self, name):
37
+ """
38
+ Add a child.
39
+
40
+ =============== ===========
41
+ **Parameters** **Type**
42
+ *typ* string
43
+ =============== ===========
44
+ """
45
+ name_prefix = 'move'
46
+ child_indexes = [int(par.name()[len(name_prefix) + 1:]) for par in self.children()]
47
+ if not child_indexes:
48
+ newindex = 0
49
+ else:
50
+ newindex = max(child_indexes) + 1
51
+
52
+ child = {'title': name, 'name': f'{name_prefix}{newindex:02.0f}', 'type': 'group', 'removable': True,
53
+ 'children': [
54
+ {'title': 'Move if overshoot?:', 'name': 'move_overshoot', 'type': 'bool', 'value': True},
55
+ {'title': 'Position:', 'name': 'position', 'type': 'float', 'value': 0}], 'removable': True,
56
+ 'renamable': False}
57
+
58
+ self.addChild(child)
59
+
60
+
61
+ registerParameterType('groupmoveover', PresetScalableGroupMove, override=True)
62
+
63
+
64
+ class PresetScalableGroupDet(GroupParameter):
65
+ """
66
+ =============== ==============
67
+ **Attributes** **Type**
68
+ *opts* dictionnary
69
+ *options* string list
70
+ =============== ==============
71
+
72
+ See Also
73
+ --------
74
+ """
75
+
76
+ def __init__(self, **opts):
77
+ opts['type'] = 'groupdetover'
78
+ opts['addText'] = "Add"
79
+ opts['addList'] = opts['detlist']
80
+ opts['movelist'] = opts['movelist']
81
+
82
+ super().__init__(**opts)
83
+
84
+ def addNew(self, name):
85
+ """
86
+ Add a child.
87
+
88
+ =============== =========== ================
89
+ **Parameters** **Type** **Description*
90
+ *typ* string the viewer name
91
+ =============== =========== ================
92
+ """
93
+ try:
94
+ name_prefix = 'det'
95
+ child_indexes = [int(par.name()[len(name_prefix) + 1:]) for par in self.children()]
96
+ if not child_indexes:
97
+ newindex = 0
98
+ else:
99
+ newindex = max(child_indexes) + 1
100
+
101
+ child = {'title': name, 'name': f'{name_prefix}{newindex:02.0f}', 'type': 'group', 'children': [
102
+ {'title': 'Trig overshoot?:', 'name': 'trig_overshoot', 'type': 'bool', 'value': True},
103
+ {'title': 'Overshoot value:', 'name': 'overshoot_value', 'type': 'float', 'value': 20},
104
+ {'title': 'Triggered Moves:', 'name': 'params', 'type': 'groupmoveover',
105
+ 'movelist': self.opts['movelist']}], 'removable': True, 'renamable': False}
106
+
107
+ self.addChild(child)
108
+ except Exception as e:
109
+ print(str(e))
110
+
111
+
112
+ registerParameterType('groupdetover', PresetScalableGroupDet, override=True)
113
+
114
+
115
+ class OvershootManager:
116
+ def __init__(self, msgbox=False, det_modules=[], actuators_modules=[]):
117
+
118
+ self.overshoot_params = None
119
+ self.det_modules = det_modules
120
+ self.actuators_modules = actuators_modules
121
+
122
+ self._activated = False
123
+
124
+ if msgbox:
125
+ msgBox = QMessageBox()
126
+ msgBox.setText("Overshoot Manager?")
127
+ msgBox.setInformativeText("What do you want to do?")
128
+ cancel_button = msgBox.addButton(QMessageBox.StandardButton.Cancel)
129
+ new_button = msgBox.addButton("New", QMessageBox.ButtonRole.ActionRole)
130
+ modify_button = msgBox.addButton("Modify", QMessageBox.ButtonRole.AcceptRole)
131
+ msgBox.setDefaultButton(QMessageBox.StandardButton.Cancel)
132
+ ret = msgBox.exec()
133
+
134
+ if msgBox.clickedButton() == new_button:
135
+ self.set_new_overshoot()
136
+
137
+ elif msgBox.clickedButton() == modify_button:
138
+ path = select_file(start_path=overshoot_path, save=False, ext='xml')
139
+ if path != '':
140
+ self.set_file_overshoot(str(path))
141
+ else: # cancel
142
+ pass
143
+
144
+ @property
145
+ def activated(self) -> bool:
146
+ return self._activated
147
+
148
+ @activated.setter
149
+ def activated(self, status: bool):
150
+ self._activated = status
151
+
152
+ def set_file_overshoot(self, filename, show=True):
153
+ """
154
+
155
+ """
156
+ children = ioxml.XML_file_to_parameter(filename)
157
+ self.overshoot_params = Parameter.create(title='Overshoot', name='Overshoot', type='group',
158
+ children=children)
159
+ if show:
160
+ self.show_overshoot()
161
+
162
+ def set_new_overshoot(self, file=None):
163
+ if file is None:
164
+ file = 'overshoot_default'
165
+ param = [{'title': 'Filename:', 'name': 'filename', 'type': 'str', 'value': file}]
166
+ params_det = [{'title': 'Detectors:', 'name': 'Detectors', 'type': 'groupdetover', 'detlist': self.det_modules,
167
+ 'movelist': self.actuators_modules}] # [PresetScalableGroupDet(name="Detectors")]
168
+ self.overshoot_params = Parameter.create(title='Preset', name='Preset', type='group',
169
+ children=param + params_det)
170
+
171
+ self.show_overshoot()
172
+
173
+ def show_overshoot(self):
174
+ """
175
+
176
+ """
177
+ dialog = QDialog()
178
+ vlayout = QtWidgets.QVBoxLayout()
179
+ tree = ParameterTree()
180
+ tree.setMinimumWidth(400)
181
+ tree.setMinimumHeight(500)
182
+ tree.setParameters(self.overshoot_params, showTop=False)
183
+
184
+ vlayout.addWidget(tree)
185
+ dialog.setLayout(vlayout)
186
+ buttonBox = QDialogButtonBox(parent=dialog)
187
+
188
+ buttonBox.addButton("Save", QDialogButtonBox.ButtonRole.AcceptRole)
189
+ buttonBox.accepted.connect(dialog.accept)
190
+ buttonBox.addButton("Cancel", QDialogButtonBox.ButtonRole.RejectRole)
191
+ buttonBox.rejected.connect(dialog.reject)
192
+
193
+ vlayout.addWidget(buttonBox)
194
+ dialog.setWindowTitle('Fill in information about this managers')
195
+ res = dialog.exec()
196
+
197
+ if res == QDialog.DialogCode.Accepted:
198
+ # save managers parameters in a xml file
199
+ # start = os.path.split(os.path.split(os.path.realpath(__file__))[0])[0]
200
+ # start = os.path.join("..",'daq_scan')
201
+ ioxml.parameter_to_xml_file(
202
+ self.overshoot_params, os.path.join(overshoot_path, self.overshoot_params.child('filename').value()))
203
+
204
+ def activate_overshoot(self, det_modules, act_modules, status: bool):
205
+ det_titles = [det.title for det in det_modules]
206
+ move_titles = [move.title for move in act_modules]
207
+
208
+ if self.overshoot_params is not None:
209
+ for det_param in self.overshoot_params.child(
210
+ 'Detectors').children():
211
+ if det_param['trig_overshoot']:
212
+ det_index = det_titles.index(det_param.opts['title'])
213
+ det_module = det_modules[det_index]
214
+ det_module.settings.child(
215
+ 'main_settings', 'overshoot', 'stop_overshoot').setValue(status)
216
+ det_module.settings.child(
217
+ 'main_settings', 'overshoot', 'overshoot_value').setValue(
218
+ det_param['overshoot_value'])
219
+ for move_param in det_param.child('params').children():
220
+ if move_param['move_overshoot']:
221
+ move_index = move_titles.index(move_param.opts['title'])
222
+ move_module = act_modules[move_index]
223
+ if status:
224
+ det_module.overshoot_signal.connect(
225
+ self.create_overshoot_fun(
226
+ move_module, move_param['position']))
227
+ else:
228
+ try:
229
+ det_module.overshoot_signal.disconnect()
230
+ except Exception as e:
231
+ pass
232
+
233
+ @staticmethod
234
+ def create_overshoot_fun(move_module, position):
235
+ return lambda: move_module.move_abs(position)
236
+
237
+
238
+ if __name__ == '__main__':
239
+ app = QtWidgets.QApplication(sys.argv)
240
+ prog = OvershootManager(True, ['det camera', 'det current'], ['Move X', 'Move Y'])
241
+
242
+ sys.exit(app.exec_())
@@ -0,0 +1,229 @@
1
+ import os
2
+ from pathlib import Path
3
+ import sys
4
+
5
+ from qtpy import QtWidgets
6
+ from qtpy.QtWidgets import QMessageBox, QDialogButtonBox, QDialog
7
+
8
+ import pymodaq_utils.config as config_mod
9
+ from pymodaq_utils.logger import set_logger, get_module_name
10
+
11
+ from pymodaq_gui.utils.file_io import select_file
12
+ from pymodaq_gui.parameter import ParameterTree, Parameter
13
+ from pymodaq_gui.parameter import ioxml
14
+ from pymodaq_gui.messenger import dialog as dialogbox
15
+ from pymodaq.utils import config as config_mod_pymodaq
16
+ from pymodaq.extensions import get_models
17
+
18
+ import pymodaq.utils.managers.preset_manager_utils # to register move and det types
19
+
20
+ logger = set_logger(get_module_name(__file__))
21
+
22
+ # check if preset_mode directory exists on the drive
23
+ preset_path = config_mod_pymodaq.get_set_preset_path()
24
+ overshoot_path = config_mod_pymodaq.get_set_overshoot_path()
25
+ layout_path = config_mod_pymodaq.get_set_layout_path()
26
+
27
+
28
+ class PresetManager:
29
+ def __init__(self, msgbox=False, path=None, extra_params=[], param_options=[]):
30
+ if path is None:
31
+ path = preset_path
32
+ else:
33
+ assert isinstance(path, Path)
34
+
35
+ self.extra_params = extra_params
36
+ self.param_options = param_options
37
+ self.preset_path = path
38
+ self.preset_params: Parameter = None
39
+
40
+ if msgbox:
41
+ msgBox = QMessageBox()
42
+ msgBox.setText("Preset Manager?")
43
+ msgBox.setInformativeText("What do you want to do?")
44
+ cancel_button = msgBox.addButton(QMessageBox.StandardButton.Cancel)
45
+ new_button = msgBox.addButton(
46
+ "New", QMessageBox.ButtonRole.ActionRole
47
+ )
48
+ modify_button = msgBox.addButton(
49
+ "Modify", QMessageBox.ButtonRole.AcceptRole
50
+ )
51
+ msgBox.setDefaultButton(QMessageBox.StandardButton.Cancel)
52
+ ret = msgBox.exec()
53
+
54
+ if msgBox.clickedButton() == new_button:
55
+ self.set_new_preset()
56
+
57
+ elif msgBox.clickedButton() == modify_button:
58
+ path = select_file(start_path=self.preset_path, save=False, ext="xml")
59
+ if path != "":
60
+ self.set_file_preset(str(path))
61
+ else: # cancel
62
+ pass
63
+
64
+ @property
65
+ def filename(self) -> str:
66
+ try:
67
+ return self.preset_params["filename"]
68
+ except:
69
+ return None
70
+
71
+ def set_file_preset(self, filename, show=True):
72
+ """ """
73
+ status = False
74
+ children = ioxml.XML_file_to_parameter(filename)
75
+ self.preset_params = Parameter.create(
76
+ title="Preset", name="Preset", type="group", children=children
77
+ )
78
+ if show:
79
+ status = self.show_preset()
80
+ return status
81
+
82
+ def set_new_preset(self):
83
+ param = [
84
+ {
85
+ "title": "Filename:",
86
+ "name": "filename",
87
+ "type": "str",
88
+ "value": "preset_default",
89
+ },
90
+ {
91
+ "title": "Model Settings:",
92
+ "name": "model_settings",
93
+ "type": "group",
94
+ "visible": False,
95
+ "children": [],
96
+ },
97
+ ]
98
+ params_move = [
99
+ {"title": "Moves:", "name": "Moves", "type": "groupmove"}
100
+ ] # PresetScalableGroupMove(name="Moves")]
101
+ params_det = [
102
+ {"title": "Detectors:", "name": "Detectors", "type": "groupdet"}
103
+ ] # [PresetScalableGroupDet(name="Detectors")]
104
+ self.preset_params = Parameter.create(
105
+ title="Preset",
106
+ name="Preset",
107
+ type="group",
108
+ children=param + self.extra_params + params_move + params_det,
109
+ )
110
+ try:
111
+ for option in self.param_options:
112
+ if "path" in option and "options_dict" in option:
113
+ self.preset_params.child(option["path"]).setOpts(
114
+ **option["options_dict"]
115
+ )
116
+ except Exception as e:
117
+ logger.exception(str(e))
118
+
119
+ self.preset_params.sigTreeStateChanged.connect(self.parameter_tree_changed)
120
+
121
+ status = self.show_preset()
122
+ return status
123
+
124
+ def parameter_tree_changed(self, param, changes):
125
+ """
126
+ Check for changes in the given (parameter,change,information) tuple list.
127
+ In case of value changed, update the DAQscan_settings tree consequently.
128
+
129
+ =============== ============================================ ==============================
130
+ **Parameters** **Type** **Description**
131
+ *param* instance of pyqtgraph parameter the parameter to be checked
132
+ *changes* (parameter,change,information) tuple list the current changes state
133
+ =============== ============================================ ==============================
134
+ """
135
+ for param, change, data in changes:
136
+ path = self.preset_params.childPath(param)
137
+ if change == "childAdded":
138
+ if len(data) > 1:
139
+ if "params" in data[0].children():
140
+ data[0].child(
141
+ "params", "main_settings", "module_name"
142
+ ).setValue(data[0].child("name").value())
143
+
144
+ elif change == "value":
145
+ if param.name() == "name":
146
+ param.parent().child(
147
+ "params", "main_settings", "module_name"
148
+ ).setValue(param.value())
149
+
150
+ elif change == "parent":
151
+ pass
152
+
153
+ def show_preset(self):
154
+ """ """
155
+ dialog = QDialog()
156
+ vlayout = QtWidgets.QVBoxLayout()
157
+ tree = ParameterTree()
158
+ # tree.setMinimumWidth(400)
159
+ # tree.setMinimumHeight(500)
160
+ tree.setParameters(self.preset_params, showTop=False)
161
+ tree.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
162
+
163
+ vlayout.addWidget(tree)
164
+ dialog.setLayout(vlayout)
165
+ buttonBox = QDialogButtonBox(parent=dialog)
166
+
167
+ buttonBox.addButton("Save", QDialogButtonBox.ButtonRole.AcceptRole)
168
+ buttonBox.accepted.connect(dialog.accept)
169
+ buttonBox.addButton("Cancel", QDialogButtonBox.ButtonRole.RejectRole)
170
+ buttonBox.rejected.connect(dialog.reject)
171
+
172
+ vlayout.addWidget(buttonBox)
173
+ dialog.setWindowTitle("Fill in information about this manager")
174
+ res = dialog.exec()
175
+
176
+ path = self.preset_path
177
+ file = None
178
+
179
+ if res == QDialog.DialogCode.Accepted:
180
+ # save managers parameters in a xml file
181
+ # start = os.path.split(os.path.split(os.path.realpath(__file__))[0])[0]
182
+ # start = os.path.join("..",'daq_scan')
183
+ filename_without_extension = self.filename
184
+
185
+ try:
186
+ ioxml.parameter_to_xml_file(
187
+ self.preset_params,
188
+ path.joinpath(filename_without_extension),
189
+ overwrite=False,
190
+ )
191
+ except FileExistsError as currenterror:
192
+ # logger.warning(str(currenterror)+"File " + filename_without_extension + ".xml exists")
193
+ logger.warning(
194
+ f"{currenterror} File {filename_without_extension}.xml exists"
195
+ )
196
+ user_agreed = dialogbox(
197
+ title="Overwrite confirmation",
198
+ message="File exist do you want to overwrite it ?",
199
+ )
200
+ if user_agreed:
201
+ ioxml.parameter_to_xml_file(
202
+ self.preset_params, path.joinpath(filename_without_extension)
203
+ )
204
+ logger.warning(
205
+ f"File {filename_without_extension}.xml overwriten at user request"
206
+ )
207
+ else:
208
+ logger.warning(
209
+ f"File {filename_without_extension}.xml wasn't saved at user request"
210
+ )
211
+ # emit status signal to dashboard to write : did not save ?
212
+ pass
213
+
214
+ # check if overshoot configuration and layout configuration with same name exists => delete them if yes
215
+ over_shoot_file = overshoot_path.joinpath(self.filename + ".xml")
216
+ over_shoot_file.unlink(missing_ok=True)
217
+
218
+ layout_file = layout_path.joinpath(self.filename + ".dock")
219
+ layout_file.unlink(missing_ok=True)
220
+
221
+ return res == QDialog.DialogCode.Accepted
222
+
223
+
224
+ if __name__ == "__main__":
225
+ app = QtWidgets.QApplication(sys.argv)
226
+ # prog = PresetManager(True)
227
+ prog = PresetManager(True)
228
+
229
+ sys.exit(app.exec_())