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.
- pymodaq/__init__.py +23 -11
- pymodaq/control_modules/__init__.py +1 -0
- pymodaq/control_modules/daq_move.py +458 -246
- pymodaq/control_modules/daq_move_ui/__init__.py +0 -0
- pymodaq/control_modules/daq_move_ui/factory.py +48 -0
- pymodaq/control_modules/{daq_move_ui.py → daq_move_ui/ui_base.py} +168 -210
- pymodaq/control_modules/daq_move_ui/uis/__init__.py +0 -0
- pymodaq/control_modules/daq_move_ui/uis/binary.py +139 -0
- pymodaq/control_modules/daq_move_ui/uis/original.py +120 -0
- pymodaq/control_modules/daq_move_ui/uis/relative.py +124 -0
- pymodaq/control_modules/daq_move_ui/uis/simple.py +126 -0
- pymodaq/control_modules/daq_viewer.py +113 -101
- pymodaq/control_modules/daq_viewer_ui.py +41 -31
- pymodaq/control_modules/mocks.py +2 -2
- pymodaq/control_modules/move_utility_classes.py +113 -41
- pymodaq/control_modules/thread_commands.py +137 -0
- pymodaq/control_modules/ui_utils.py +72 -0
- pymodaq/control_modules/utils.py +107 -63
- pymodaq/control_modules/viewer_utility_classes.py +13 -17
- pymodaq/dashboard.py +1294 -625
- pymodaq/examples/qt_less_standalone_module.py +48 -11
- pymodaq/extensions/__init__.py +8 -3
- pymodaq/extensions/adaptive/__init__.py +2 -0
- pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
- pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
- pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
- pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
- pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
- pymodaq/extensions/adaptive/utils.py +123 -0
- pymodaq/extensions/bayesian/__init__.py +1 -1
- pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
- pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
- pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
- pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
- pymodaq/extensions/bayesian/utils.py +71 -297
- pymodaq/extensions/daq_logger/daq_logger.py +7 -12
- pymodaq/extensions/daq_logger/h5logging.py +1 -1
- pymodaq/extensions/daq_scan.py +30 -55
- pymodaq/extensions/data_mixer/__init__.py +0 -0
- pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
- pymodaq/extensions/data_mixer/data_mixer.py +262 -0
- pymodaq/extensions/data_mixer/model.py +108 -0
- pymodaq/extensions/data_mixer/models/__init__.py +0 -0
- pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
- pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
- pymodaq/extensions/data_mixer/parser.py +53 -0
- pymodaq/extensions/data_mixer/utils.py +23 -0
- pymodaq/extensions/h5browser.py +3 -34
- pymodaq/extensions/optimizers_base/__init__.py +0 -0
- pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
- pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
- pymodaq/extensions/optimizers_base/utils.py +427 -0
- pymodaq/extensions/pid/actuator_controller.py +3 -2
- pymodaq/extensions/pid/daq_move_PID.py +107 -30
- pymodaq/extensions/pid/pid_controller.py +613 -287
- pymodaq/extensions/pid/utils.py +8 -5
- pymodaq/extensions/utils.py +17 -2
- pymodaq/resources/config_template.toml +57 -0
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/utils/config.py +13 -4
- pymodaq/utils/daq_utils.py +14 -0
- pymodaq/utils/data.py +1 -0
- pymodaq/utils/gui_utils/loader_utils.py +25 -15
- pymodaq/utils/h5modules/module_saving.py +134 -22
- pymodaq/utils/leco/daq_move_LECODirector.py +123 -84
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +84 -97
- pymodaq/utils/leco/director_utils.py +32 -16
- pymodaq/utils/leco/leco_director.py +104 -27
- pymodaq/utils/leco/pymodaq_listener.py +186 -97
- pymodaq/utils/leco/rpc_method_definitions.py +43 -0
- pymodaq/utils/leco/utils.py +25 -25
- pymodaq/utils/managers/batchscan_manager.py +12 -11
- pymodaq/utils/managers/modules_manager.py +74 -33
- pymodaq/utils/managers/overshoot_manager.py +11 -10
- pymodaq/utils/managers/preset_manager.py +100 -64
- pymodaq/utils/managers/preset_manager_utils.py +163 -107
- pymodaq/utils/managers/remote_manager.py +21 -16
- pymodaq/utils/scanner/scan_factory.py +18 -4
- pymodaq/utils/scanner/scan_selector.py +1 -3
- pymodaq/utils/scanner/scanner.py +35 -6
- pymodaq/utils/scanner/scanners/_1d_scanners.py +15 -46
- pymodaq/utils/scanner/scanners/_2d_scanners.py +21 -68
- pymodaq/utils/scanner/scanners/sequential.py +50 -31
- pymodaq/utils/scanner/scanners/tabular.py +45 -28
- {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/METADATA +7 -6
- pymodaq-5.1.0.dist-info/RECORD +154 -0
- {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/entry_points.txt +0 -2
- pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -685
- pymodaq/utils/leco/desktop.ini +0 -2
- pymodaq-5.0.17.dist-info/RECORD +0 -121
- {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/WHEEL +0 -0
- {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
|
pymodaq/extensions/h5browser.py
CHANGED
|
@@ -1,39 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
from
|
|
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
|
-
|
|
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
|