pymodaq 5.0.17__py3-none-any.whl → 5.1.0__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 (92) hide show
  1. pymodaq/__init__.py +23 -11
  2. pymodaq/control_modules/__init__.py +1 -0
  3. pymodaq/control_modules/daq_move.py +458 -246
  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.py → daq_move_ui/ui_base.py} +168 -210
  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 +113 -101
  13. pymodaq/control_modules/daq_viewer_ui.py +41 -31
  14. pymodaq/control_modules/mocks.py +2 -2
  15. pymodaq/control_modules/move_utility_classes.py +113 -41
  16. pymodaq/control_modules/thread_commands.py +137 -0
  17. pymodaq/control_modules/ui_utils.py +72 -0
  18. pymodaq/control_modules/utils.py +107 -63
  19. pymodaq/control_modules/viewer_utility_classes.py +13 -17
  20. pymodaq/dashboard.py +1294 -625
  21. pymodaq/examples/qt_less_standalone_module.py +48 -11
  22. pymodaq/extensions/__init__.py +8 -3
  23. pymodaq/extensions/adaptive/__init__.py +2 -0
  24. pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
  25. pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
  26. pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
  27. pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
  28. pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
  29. pymodaq/extensions/adaptive/utils.py +123 -0
  30. pymodaq/extensions/bayesian/__init__.py +1 -1
  31. pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
  32. pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
  33. pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
  34. pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
  35. pymodaq/extensions/bayesian/utils.py +71 -297
  36. pymodaq/extensions/daq_logger/daq_logger.py +7 -12
  37. pymodaq/extensions/daq_logger/h5logging.py +1 -1
  38. pymodaq/extensions/daq_scan.py +30 -55
  39. pymodaq/extensions/data_mixer/__init__.py +0 -0
  40. pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
  41. pymodaq/extensions/data_mixer/data_mixer.py +262 -0
  42. pymodaq/extensions/data_mixer/model.py +108 -0
  43. pymodaq/extensions/data_mixer/models/__init__.py +0 -0
  44. pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
  45. pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
  46. pymodaq/extensions/data_mixer/parser.py +53 -0
  47. pymodaq/extensions/data_mixer/utils.py +23 -0
  48. pymodaq/extensions/h5browser.py +3 -34
  49. pymodaq/extensions/optimizers_base/__init__.py +0 -0
  50. pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
  51. pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
  52. pymodaq/extensions/optimizers_base/utils.py +427 -0
  53. pymodaq/extensions/pid/actuator_controller.py +3 -2
  54. pymodaq/extensions/pid/daq_move_PID.py +107 -30
  55. pymodaq/extensions/pid/pid_controller.py +613 -287
  56. pymodaq/extensions/pid/utils.py +8 -5
  57. pymodaq/extensions/utils.py +17 -2
  58. pymodaq/resources/config_template.toml +57 -0
  59. pymodaq/resources/preset_default.xml +1 -1
  60. pymodaq/utils/config.py +13 -4
  61. pymodaq/utils/daq_utils.py +14 -0
  62. pymodaq/utils/data.py +1 -0
  63. pymodaq/utils/gui_utils/loader_utils.py +25 -15
  64. pymodaq/utils/h5modules/module_saving.py +134 -22
  65. pymodaq/utils/leco/daq_move_LECODirector.py +123 -84
  66. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +84 -97
  67. pymodaq/utils/leco/director_utils.py +32 -16
  68. pymodaq/utils/leco/leco_director.py +104 -27
  69. pymodaq/utils/leco/pymodaq_listener.py +186 -97
  70. pymodaq/utils/leco/rpc_method_definitions.py +43 -0
  71. pymodaq/utils/leco/utils.py +25 -25
  72. pymodaq/utils/managers/batchscan_manager.py +12 -11
  73. pymodaq/utils/managers/modules_manager.py +74 -33
  74. pymodaq/utils/managers/overshoot_manager.py +11 -10
  75. pymodaq/utils/managers/preset_manager.py +100 -64
  76. pymodaq/utils/managers/preset_manager_utils.py +163 -107
  77. pymodaq/utils/managers/remote_manager.py +21 -16
  78. pymodaq/utils/scanner/scan_factory.py +18 -4
  79. pymodaq/utils/scanner/scan_selector.py +1 -3
  80. pymodaq/utils/scanner/scanner.py +35 -6
  81. pymodaq/utils/scanner/scanners/_1d_scanners.py +15 -46
  82. pymodaq/utils/scanner/scanners/_2d_scanners.py +21 -68
  83. pymodaq/utils/scanner/scanners/sequential.py +50 -31
  84. pymodaq/utils/scanner/scanners/tabular.py +45 -28
  85. {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/METADATA +7 -6
  86. pymodaq-5.1.0.dist-info/RECORD +154 -0
  87. {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/entry_points.txt +0 -2
  88. pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -685
  89. pymodaq/utils/leco/desktop.ini +0 -2
  90. pymodaq-5.0.17.dist-info/RECORD +0 -121
  91. {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/WHEEL +0 -0
  92. {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,91 @@
1
+ from pymodaq.extensions.data_mixer.model import DataMixerModel, np # np will be used in method eval of the formula
2
+
3
+ from pymodaq_data.data import DataToExport, DataWithAxes
4
+ from pymodaq_gui.parameter import Parameter
5
+ from pymodaq_gui.config_saver_loader import ConfigSaverLoader
6
+
7
+ from pymodaq.extensions.data_mixer.parser import (
8
+ extract_data_names, split_formulae, replace_names_in_formula)
9
+
10
+ from pymodaq_utils.logger import set_logger, get_module_name
11
+
12
+ logger = set_logger(get_module_name(__file__))
13
+
14
+ class DataMixerModelEquation(DataMixerModel):
15
+ params = [
16
+ {'title': 'Get Data:', 'name': 'get_data', 'type': 'bool_push', 'value': False,
17
+ 'label': 'Get Data'},
18
+ {'title': 'Edit Formula:', 'name': 'edit_formula', 'type': 'text', 'value': ''},
19
+ {'title': 'Data0D:', 'name': 'data0D', 'type': 'itemselect',
20
+ 'value': dict(all_items=[], selected=[])},
21
+ {'title': 'Data1D:', 'name': 'data1D', 'type': 'itemselect',
22
+ 'value': dict(all_items=[], selected=[])},
23
+ {'title': 'Data2D:', 'name': 'data2D', 'type': 'itemselect',
24
+ 'value': dict(all_items=[], selected=[])},
25
+ {'title': 'DataND:', 'name': 'dataND', 'type': 'itemselect',
26
+ 'value': dict(all_items=[], selected=[])},
27
+ ]
28
+
29
+ def ini_model(self):
30
+ self.model_saver_loader = ConfigSaverLoader(self.settings, self.data_mixer.datamixer_config,
31
+ base_path=[self.__class__.__name__])
32
+ self.show_data_list()
33
+ self.model_saver_loader.load_config()
34
+
35
+ def update_settings(self, param: Parameter):
36
+ if param.name() == 'get_data':
37
+ self.show_data_list()
38
+ elif param.name() == 'edit_formula':
39
+ self.model_saver_loader.save_config(param)
40
+
41
+ def process_dte(self, dte: DataToExport):
42
+ formulae = split_formulae(self.get_formulae())
43
+ dte_processed = DataToExport('Computed')
44
+ for ind, formula in enumerate(formulae):
45
+ try:
46
+ dwa = self.compute_formula(formula, dte,
47
+ name=f'Formula_{ind:03.0f}')
48
+ dte_processed.append(dwa)
49
+ except Exception as e:
50
+ logger.exception(f'{str(e)}')
51
+ return dte_processed
52
+
53
+ def get_formulae(self) -> str:
54
+ """ Read the content of the formula QTextEdit widget"""
55
+ return self.settings['edit_formula']
56
+
57
+ def show_data_list(self):
58
+ dte = self.modules_manager.get_det_data_list()
59
+
60
+ data_list0D = dte.get_full_names('data0D')
61
+ data_list1D = dte.get_full_names('data1D')
62
+ data_list2D = dte.get_full_names('data2D')
63
+ data_listND = dte.get_full_names('dataND')
64
+
65
+ self.settings.child('data0D').setValue(dict(all_items=data_list0D, selected=[]))
66
+ self.settings.child('data1D').setValue(dict(all_items=data_list1D, selected=[]))
67
+ self.settings.child('data2D').setValue(dict(all_items=data_list2D, selected=[]))
68
+ self.settings.child('dataND').setValue(dict(all_items=data_listND, selected=[]))
69
+
70
+
71
+ def compute_formula(self, formula: str, dte: DataToExport,
72
+ name: str) -> DataWithAxes:
73
+ """ Compute the operations in formula using data stored in dte
74
+
75
+ Parameters
76
+ ----------
77
+ formula: str
78
+ The mathematical formula using numpy and data fullnames within curly brackets
79
+ dte: DataToExport
80
+ name: str
81
+ The name to give to the produced DataWithAxes
82
+
83
+ Returns
84
+ -------
85
+ DataWithAxes: the results of the formula computation
86
+ """
87
+ formula_to_eval, names = replace_names_in_formula(formula)
88
+ dwa = eval(formula_to_eval)
89
+ dwa.name = name
90
+ return dwa
91
+
@@ -0,0 +1,65 @@
1
+ import numpy as np
2
+
3
+ from pymodaq.extensions.data_mixer.model import DataMixerModel, np # np will be used in method eval of the formula
4
+
5
+ from pymodaq_utils.math_utils import gauss1D, my_moment
6
+
7
+ from pymodaq_data.data import DataToExport, DataWithAxes, DataCalculated, DataDim
8
+ from pymodaq_gui.parameter import Parameter
9
+
10
+ from pymodaq.extensions.data_mixer.parser import (
11
+ extract_data_names, split_formulae, replace_names_in_formula)
12
+
13
+
14
+ def gaussian_fit(x, amp, x0, dx, offset):
15
+ dx = np.abs(dx)
16
+ return amp * gauss1D(x, x0, dx) + offset
17
+
18
+
19
+ class DataMixerGaussianFitModel(DataMixerModel):
20
+ params = [
21
+ {'title': 'Get Data:', 'name': 'get_data', 'type': 'bool_push', 'value': False,
22
+ 'label': 'Get Data'},
23
+ {'title': 'Data1D:', 'name': 'data1D', 'type': 'itemselect',
24
+ 'value': dict(all_items=[], selected=[])},
25
+ ]
26
+
27
+ def ini_model(self):
28
+ self.show_data_list()
29
+
30
+ def show_data_list(self):
31
+ dte = self.modules_manager.get_det_data_list()
32
+ data_list1D = dte.get_full_names('data1D')
33
+ self.settings.child('data1D').setValue(dict(all_items=data_list1D, selected=[]))
34
+
35
+ def update_settings(self, param: Parameter):
36
+ if param.name() == 'get_data':
37
+ self.show_data_list()
38
+
39
+ def process_dte(self, dte: DataToExport):
40
+ dte_processed = DataToExport('computed')
41
+ if len(self.settings['data1D']['selected']) != 0:
42
+
43
+ dwa = dte.get_data_from_full_name(self.settings['data1D']['selected'][0])
44
+ dwa_fit = dwa.fit(gaussian_fit, self.get_guess(dwa), data_index=0)
45
+ dwa.append(dwa_fit)
46
+ dte_processed.append(dwa)
47
+ dte_processed.append(
48
+ DataCalculated('Coeffs',
49
+ data=[np.atleast_1d(coeff) for coeff in dwa_fit.fit_coeffs[0]],
50
+ labels=['amp', 'x0', 'dx', 'offset']))
51
+
52
+ return dte_processed
53
+
54
+ @staticmethod
55
+ def get_guess(dwa):
56
+ offset = np.min(dwa).value()
57
+ dwa.create_missing_axes()
58
+ moments = my_moment(dwa.axes[0].get_data(), dwa.data[0])
59
+ amp = (np.max(dwa) - np.min(dwa)).value()
60
+ x0 = float(moments[0])
61
+ dx = float(moments[1])
62
+
63
+ return amp, x0, dx, offset
64
+
65
+
@@ -0,0 +1,53 @@
1
+ import re
2
+ from typing import List
3
+
4
+
5
+ data_name_regexp = re.compile(r"({.*?})+") # first occurrences of things between {}
6
+
7
+
8
+ def split_formulae(formulae: str) -> List[str]:
9
+ """ Split a string into a list of string for each new line
10
+
11
+ Parameters
12
+ ----------
13
+ formulae: str
14
+ The formulae containing various mathematical formula separated with a new line character
15
+
16
+ Returns
17
+ -------
18
+ The various formula as a list of string
19
+ """
20
+ return re.split(r'\n', formulae)
21
+
22
+
23
+ def extract_data_names(formula: str) -> List[str]:
24
+ """ Extract the names of the data appearing between curly brackets with a given string formula
25
+
26
+ Parameters
27
+ ----------
28
+ formula: str
29
+ The mathematical expression to compute containing in curly brackets the data full names
30
+
31
+ Returns
32
+ -------
33
+
34
+ """
35
+ data_names = [data_name_with_curly[1:-1] for
36
+ data_name_with_curly in data_name_regexp.findall(formula)]
37
+ return data_names
38
+
39
+
40
+ def replace_names_in_formula(formula: str):
41
+ formula_tmp = formula[:]
42
+ names = []
43
+ while True:
44
+ m = data_name_regexp.search(formula_tmp)
45
+ if m is not None:
46
+ names.append(m.group())
47
+ formula_tmp = (
48
+ formula_tmp.replace(formula_tmp[m.start(): m.end()],
49
+ f'dte.get_data_from_full_name("{m.group()[1:-1]}")'))
50
+ else:
51
+ break
52
+ return formula_tmp, names
53
+
@@ -0,0 +1,23 @@
1
+ from pymodaq_utils.config import BaseConfig
2
+
3
+
4
+ class DataMixerConfig(BaseConfig):
5
+ """Main class to deal with configuration values for this plugin
6
+
7
+ To b subclassed for real implementation if needed, see Optimizer class attribute config_saver
8
+ """
9
+ config_template_path = None
10
+ config_name = f"datamixer_settings"
11
+
12
+
13
+ def find_key_in_nested_dict(dic, key):
14
+ stack = [dic]
15
+ while stack:
16
+ d = stack.pop()
17
+ if key in d:
18
+ return d[key]
19
+ for v in d.values():
20
+ if isinstance(v, dict):
21
+ stack.append(v)
22
+ if isinstance(v, list):
23
+ stack += v
@@ -1,39 +1,8 @@
1
- import argparse
2
- from pathlib import Path
3
- import sys
4
- import os
5
- from qtpy import QtWidgets
6
- os.environ["HDF5_USE_FILE_LOCKING"] = "FALSE"
7
- from pymodaq_gui.h5modules.browsing import H5Browser
8
- from pymodaq.utils.config import Config
1
+ from pymodaq_gui.h5modules.h5browser import main, H5Browser #backcompat
2
+ from pymodaq_utils.utils import deprecation_msg
9
3
 
10
4
 
11
- config = Config()
12
-
13
-
14
- def main(h5file_path: Path = None):
15
- from pymodaq_gui.utils.utils import mkQApp
16
- import sys
17
- app = mkQApp('H5Browser')
18
-
19
- h5file_path_tmp = None
20
- parser = argparse.ArgumentParser(description="Opens HDF5 files and navigate their contents")
21
- parser.add_argument("-i", "--input", help="specify path to the file to be opened")
22
- args = parser.parse_args()
23
-
24
- if args.input:
25
- h5file_path_tmp = Path(args.input).resolve() # Transform to absolute Path in case it is relative
26
-
27
- if not h5file_path_tmp.exists():
28
- print(f'Error: {args.input} does not exist. Opening h5browser without input file.')
29
- h5file_path_tmp = h5file_path
30
-
31
- win = QtWidgets.QMainWindow()
32
- prog = H5Browser(win, h5file_path=h5file_path_tmp)
33
- win.show()
34
- QtWidgets.QApplication.processEvents()
35
-
36
- app.exec()
5
+ deprecation_msg('H5Browser should now be loaded from the pymodaq_gui.h5modules.h5browser module')
37
6
 
38
7
 
39
8
  if __name__ == '__main__':
File without changes