pymodaq 3.6.12__py3-none-any.whl → 4.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +13 -6
- pymodaq/control_modules/__init__.py +0 -7
- pymodaq/control_modules/daq_move.py +965 -2
- pymodaq/control_modules/daq_move_ui.py +319 -0
- pymodaq/control_modules/daq_viewer.py +1573 -3
- pymodaq/control_modules/daq_viewer_ui.py +393 -0
- pymodaq/control_modules/mocks.py +51 -0
- pymodaq/control_modules/move_utility_classes.py +709 -8
- pymodaq/control_modules/utils.py +256 -0
- pymodaq/control_modules/viewer_utility_classes.py +663 -6
- pymodaq/daq_utils.py +89 -0
- pymodaq/dashboard.py +91 -72
- pymodaq/examples/custom_app.py +12 -11
- pymodaq/examples/custom_viewer.py +10 -10
- pymodaq/examples/function_plotter.py +16 -13
- pymodaq/examples/nonlinearscanner.py +8 -6
- pymodaq/examples/parameter_ex.py +7 -7
- pymodaq/examples/preset_MockCamera.xml +1 -0
- pymodaq/extensions/__init__.py +16 -0
- pymodaq/extensions/console.py +76 -0
- pymodaq/{daq_logger.py → extensions/daq_logger.py} +115 -65
- pymodaq/extensions/daq_scan.py +1339 -0
- pymodaq/extensions/daq_scan_ui.py +240 -0
- pymodaq/extensions/h5browser.py +23 -0
- pymodaq/{pid → extensions/pid}/__init__.py +4 -2
- pymodaq/{pid → extensions/pid}/daq_move_PID.py +2 -2
- pymodaq/{pid → extensions/pid}/pid_controller.py +48 -36
- pymodaq/{pid → extensions/pid}/utils.py +52 -6
- pymodaq/extensions/utils.py +40 -0
- pymodaq/post_treatment/__init__.py +6 -0
- pymodaq/{daq_analysis → post_treatment/daq_analysis}/daq_analysis_main.py +17 -17
- pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_main.py +8 -14
- pymodaq/post_treatment/load_and_plot.py +219 -0
- pymodaq/post_treatment/process_to_scalar.py +263 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +1 -1
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +1 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +109784 -109173
- pymodaq/resources/QtDesigner_Ressources/icons.svg +142 -0
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/config_template.toml +32 -13
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/{daq_utils → utils}/Tuto innosetup/script_full_setup.iss +1 -1
- pymodaq/utils/__init__.py +0 -29
- pymodaq/utils/abstract/__init__.py +48 -0
- pymodaq/{daq_utils → utils}/abstract/logger.py +7 -3
- pymodaq/utils/array_manipulation.py +379 -8
- pymodaq/{daq_utils → utils}/calibration_camera.py +6 -6
- pymodaq/{daq_utils → utils}/chrono_timer.py +1 -1
- pymodaq/utils/config.py +448 -0
- pymodaq/utils/conftests.py +5 -0
- pymodaq/utils/daq_utils.py +828 -8
- pymodaq/utils/data.py +1873 -7
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger.py +86 -47
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger_models.py +31 -10
- pymodaq/{daq_utils → utils}/enums.py +12 -7
- pymodaq/utils/exceptions.py +37 -0
- pymodaq/utils/factory.py +82 -0
- pymodaq/{daq_utils → utils}/gui_utils/__init__.py +1 -1
- pymodaq/utils/gui_utils/custom_app.py +129 -0
- pymodaq/utils/gui_utils/file_io.py +66 -0
- pymodaq/{daq_utils → utils}/gui_utils/layout.py +2 -2
- pymodaq/{daq_utils → utils}/gui_utils/utils.py +13 -3
- pymodaq/{daq_utils → utils}/gui_utils/widgets/__init__.py +2 -2
- pymodaq/utils/gui_utils/widgets/label.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/lcd.py +12 -7
- pymodaq/{daq_utils → utils}/gui_utils/widgets/push.py +66 -2
- pymodaq/{daq_utils → utils}/gui_utils/widgets/qled.py +6 -4
- pymodaq/utils/gui_utils/widgets/spinbox.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/table.py +2 -2
- pymodaq/utils/h5modules/__init__.py +1 -0
- pymodaq/{daq_utils/h5backend.py → utils/h5modules/backends.py} +200 -112
- pymodaq/utils/h5modules/browsing.py +683 -0
- pymodaq/utils/h5modules/data_saving.py +839 -0
- pymodaq/utils/h5modules/h5logging.py +110 -0
- pymodaq/utils/h5modules/module_saving.py +350 -0
- pymodaq/utils/h5modules/saving.py +914 -0
- pymodaq/utils/h5modules/utils.py +85 -0
- pymodaq/utils/logger.py +64 -6
- pymodaq/utils/managers/action_manager.py +460 -0
- pymodaq/{daq_utils → utils}/managers/batchscan_manager.py +144 -112
- pymodaq/{daq_utils → utils}/managers/modules_manager.py +188 -114
- pymodaq/{daq_utils → utils}/managers/overshoot_manager.py +3 -3
- pymodaq/utils/managers/parameter_manager.py +110 -0
- pymodaq/{daq_utils → utils}/managers/preset_manager.py +17 -13
- pymodaq/{daq_utils → utils}/managers/preset_manager_utils.py +8 -7
- pymodaq/{daq_utils → utils}/managers/remote_manager.py +7 -6
- pymodaq/{daq_utils → utils}/managers/roi_manager.py +148 -57
- pymodaq/utils/math_utils.py +546 -10
- pymodaq/{daq_utils → utils}/messenger.py +5 -1
- pymodaq/utils/parameter/__init__.py +2 -15
- pymodaq/{daq_utils → utils}/parameter/ioxml.py +12 -6
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/__init__.py +1 -3
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/filedir.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/itemselect.py +3 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/led.py +1 -1
- pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +161 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/slide.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/table.py +1 -1
- pymodaq/utils/parameter/utils.py +206 -11
- pymodaq/utils/plotting/data_viewers/__init__.py +6 -0
- pymodaq/utils/plotting/data_viewers/viewer.py +393 -0
- pymodaq/utils/plotting/data_viewers/viewer0D.py +251 -0
- pymodaq/utils/plotting/data_viewers/viewer1D.py +574 -0
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer1Dbasic.py +8 -3
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D.py +292 -357
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D_basic.py +58 -75
- pymodaq/utils/plotting/data_viewers/viewerND.py +738 -0
- pymodaq/{daq_utils → utils}/plotting/gant_chart.py +2 -2
- pymodaq/{daq_utils → utils}/plotting/items/axis_scaled.py +4 -2
- pymodaq/{daq_utils → utils}/plotting/items/image.py +8 -6
- pymodaq/utils/plotting/navigator.py +355 -0
- pymodaq/utils/plotting/scan_selector.py +480 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +88 -0
- pymodaq/utils/plotting/utils/filter.py +538 -0
- pymodaq/utils/plotting/utils/lineout.py +224 -0
- pymodaq/{daq_utils → utils}/plotting/utils/plot_utils.py +196 -84
- pymodaq/{daq_utils → utils}/plotting/utils/signalND.py +21 -13
- pymodaq/utils/plotting/widgets.py +76 -0
- pymodaq/utils/scanner/__init__.py +10 -0
- pymodaq/utils/scanner/scan_factory.py +204 -0
- pymodaq/utils/scanner/scanner.py +271 -0
- pymodaq/utils/scanner/scanners/_1d_scanners.py +117 -0
- pymodaq/utils/scanner/scanners/_2d_scanners.py +293 -0
- pymodaq/utils/scanner/scanners/sequential.py +192 -0
- pymodaq/utils/scanner/scanners/tabular.py +294 -0
- pymodaq/utils/scanner/utils.py +83 -0
- pymodaq/utils/slicing.py +47 -0
- pymodaq/utils/svg/__init__.py +6 -0
- pymodaq/utils/svg/svg_renderer.py +20 -0
- pymodaq/utils/svg/svg_view.py +35 -0
- pymodaq/utils/svg/svg_viewer2D.py +51 -0
- pymodaq/{daq_utils → utils}/tcp_server_client.py +36 -37
- pymodaq/{daq_utils → utils}/tree_layout/tree_layout_main.py +50 -35
- pymodaq/utils/units.py +216 -0
- pymodaq-4.0.1.dist-info/METADATA +159 -0
- {pymodaq-3.6.12.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
- {pymodaq-3.6.12.dist-info → pymodaq-4.0.1.dist-info}/WHEEL +1 -2
- pymodaq-4.0.1.dist-info/entry_points.txt +8 -0
- pymodaq/daq_move/daq_move_gui.py +0 -279
- pymodaq/daq_move/daq_move_gui.ui +0 -534
- pymodaq/daq_move/daq_move_main.py +0 -1042
- pymodaq/daq_move/process_from_QtDesigner_DAQ_Move_GUI.bat +0 -2
- pymodaq/daq_move/utility_classes.py +0 -671
- pymodaq/daq_scan.py +0 -2160
- pymodaq/daq_utils/array_manipulation.py +0 -386
- pymodaq/daq_utils/config.py +0 -273
- pymodaq/daq_utils/conftests.py +0 -7
- pymodaq/daq_utils/custom_parameter_tree.py +0 -9
- pymodaq/daq_utils/daq_enums.py +0 -133
- pymodaq/daq_utils/daq_utils.py +0 -1402
- pymodaq/daq_utils/exceptions.py +0 -71
- pymodaq/daq_utils/gui_utils/custom_app.py +0 -103
- pymodaq/daq_utils/gui_utils/file_io.py +0 -75
- pymodaq/daq_utils/gui_utils/widgets/spinbox.py +0 -9
- pymodaq/daq_utils/h5exporter_hyperspy.py +0 -115
- pymodaq/daq_utils/h5exporters.py +0 -242
- pymodaq/daq_utils/h5modules.py +0 -1559
- pymodaq/daq_utils/h5utils.py +0 -241
- pymodaq/daq_utils/managers/action_manager.py +0 -236
- pymodaq/daq_utils/managers/parameter_manager.py +0 -57
- pymodaq/daq_utils/math_utils.py +0 -705
- pymodaq/daq_utils/parameter/__init__.py +0 -1
- pymodaq/daq_utils/parameter/oldpymodaq_ptypes.py +0 -1626
- pymodaq/daq_utils/parameter/pymodaq_ptypes/pixmap.py +0 -85
- pymodaq/daq_utils/parameter/utils.py +0 -136
- pymodaq/daq_utils/plotting/data_viewers/__init__.py +0 -0
- pymodaq/daq_utils/plotting/data_viewers/process_from_QtDesigner_0DViewer_GUI.bat +0 -2
- pymodaq/daq_utils/plotting/data_viewers/viewer0D.py +0 -204
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.py +0 -89
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.ui +0 -131
- pymodaq/daq_utils/plotting/data_viewers/viewer1D.py +0 -781
- pymodaq/daq_utils/plotting/data_viewers/viewerND.py +0 -894
- pymodaq/daq_utils/plotting/data_viewers/viewerbase.py +0 -64
- pymodaq/daq_utils/plotting/items/__init__.py +0 -0
- pymodaq/daq_utils/plotting/navigator.py +0 -500
- pymodaq/daq_utils/plotting/scan_selector.py +0 -289
- pymodaq/daq_utils/plotting/utils/__init__.py +0 -0
- pymodaq/daq_utils/plotting/utils/filter.py +0 -236
- pymodaq/daq_utils/plotting/viewer0D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer0D/viewer0D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer1D/viewer1D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/viewer1Dbasic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_basic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewerND/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewerND/viewerND_main.py +0 -4
- pymodaq/daq_utils/scanner.py +0 -1289
- pymodaq/daq_utils/tree_layout/__init__.py +0 -0
- pymodaq/daq_viewer/__init__.py +0 -0
- pymodaq/daq_viewer/daq_gui_settings.py +0 -237
- pymodaq/daq_viewer/daq_gui_settings.ui +0 -441
- pymodaq/daq_viewer/daq_viewer_main.py +0 -2225
- pymodaq/daq_viewer/process_from_QtDesigner_DAQ_GUI_settings.bat +0 -2
- pymodaq/daq_viewer/utility_classes.py +0 -673
- pymodaq/examples/logger_image/__init__.py +0 -0
- pymodaq/examples/logger_image/logger_displayer.py +0 -121
- pymodaq/examples/logger_image/setup.svg +0 -3119
- pymodaq/examples/logger_image/setup_svg.py +0 -114
- pymodaq/h5browser.py +0 -39
- pymodaq/utils/scanner.py +0 -15
- pymodaq-3.6.12.dist-info/METADATA +0 -39
- pymodaq-3.6.12.dist-info/entry_points.txt +0 -8
- pymodaq-3.6.12.dist-info/top_level.txt +0 -1
- /pymodaq/{daq_analysis → post_treatment/daq_analysis}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.ui +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.odt +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.pdf +0 -0
- /pymodaq/{daq_move → utils/db}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils/db/db_logger}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/dock.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/list_picker.py +0 -0
- /pymodaq/{daq_utils/abstract → utils/managers}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/bool.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/date.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/list.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/numeric.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/tableview.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/text.py +0 -0
- /pymodaq/{daq_utils/db → utils/plotting}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/image_viewer.py +0 -0
- /pymodaq/{daq_utils/db/db_logger → utils/plotting/items}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/items/crosshair.py +0 -0
- /pymodaq/{daq_utils/managers → utils/plotting/utils}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/qvariant.py +0 -0
- /pymodaq/{daq_utils/plotting/viewer2D → utils/scanner/scanners}/__init__.py +0 -0
- /pymodaq/{daq_utils/plotting → utils/tree_layout}/__init__.py +0 -0
- {pymodaq-3.6.12.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,2225 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created on Wed Jan 10 16:54:14 2018
|
|
4
|
-
|
|
5
|
-
@author: Weber Sébastien
|
|
6
|
-
"""
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
from pymodaq.daq_utils.gui_utils.file_io import select_file
|
|
10
|
-
import pymodaq.daq_utils.gui_utils.utils
|
|
11
|
-
from qtpy import QtGui, QtWidgets, QtCore
|
|
12
|
-
from qtpy.QtCore import Qt, QObject, Slot, QThread, Signal, QRectF
|
|
13
|
-
import sys
|
|
14
|
-
from typing import List
|
|
15
|
-
import pymodaq.daq_utils.scanner
|
|
16
|
-
from pymodaq.daq_viewer.daq_gui_settings import Ui_Form
|
|
17
|
-
import copy
|
|
18
|
-
|
|
19
|
-
from pymodaq.daq_utils.plotting.data_viewers.viewer0D import Viewer0D
|
|
20
|
-
from pymodaq.daq_utils.plotting.data_viewers.viewer1D import Viewer1D
|
|
21
|
-
from pymodaq.daq_utils.plotting.data_viewers.viewer2D import Viewer2D
|
|
22
|
-
from pymodaq.daq_utils.plotting.data_viewers.viewerND import ViewerND
|
|
23
|
-
from pymodaq.daq_utils.scanner import Scanner
|
|
24
|
-
from pymodaq.daq_utils.plotting.navigator import Navigator
|
|
25
|
-
from pymodaq.daq_utils.tcp_server_client import TCPClient
|
|
26
|
-
from pymodaq.daq_utils.gui_utils.widgets.lcd import LCD
|
|
27
|
-
from pymodaq.daq_utils.config import Config, get_set_local_dir
|
|
28
|
-
from pymodaq.daq_utils import gui_utils as gutils
|
|
29
|
-
from pymodaq.daq_utils.h5modules import browse_data
|
|
30
|
-
from pymodaq.daq_utils.daq_utils import ThreadCommand, get_plugins
|
|
31
|
-
from pymodaq.daq_utils.exceptions import DetectorError
|
|
32
|
-
|
|
33
|
-
from collections import OrderedDict
|
|
34
|
-
import numpy as np
|
|
35
|
-
|
|
36
|
-
from pyqtgraph.parametertree import Parameter, ParameterTree
|
|
37
|
-
from pymodaq.daq_utils.parameter import ioxml
|
|
38
|
-
from pymodaq.daq_utils.parameter import utils as putils
|
|
39
|
-
|
|
40
|
-
from easydict import EasyDict as edict
|
|
41
|
-
from pymodaq.daq_viewer.utility_classes import params as daq_viewer_params
|
|
42
|
-
import pickle
|
|
43
|
-
import time
|
|
44
|
-
import datetime
|
|
45
|
-
import tables
|
|
46
|
-
from pathlib import Path
|
|
47
|
-
from pymodaq.daq_utils.h5modules import H5Saver
|
|
48
|
-
from pymodaq.daq_utils import daq_utils as utils
|
|
49
|
-
from pymodaq.daq_utils.gui_utils import DockArea, Dock
|
|
50
|
-
|
|
51
|
-
logger = utils.set_logger(utils.get_module_name(__file__))
|
|
52
|
-
config = Config()
|
|
53
|
-
|
|
54
|
-
local_path = get_set_local_dir()
|
|
55
|
-
|
|
56
|
-
DAQ_0DViewer_Det_types = get_plugins('daq_0Dviewer')
|
|
57
|
-
DAQ_1DViewer_Det_types = get_plugins('daq_1Dviewer')
|
|
58
|
-
DAQ_2DViewer_Det_types = get_plugins('daq_2Dviewer')
|
|
59
|
-
DAQ_NDViewer_Det_types = get_plugins('daq_NDviewer')
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class DAQ_Viewer(QObject):
|
|
63
|
-
"""
|
|
64
|
-
========================= =======================================
|
|
65
|
-
**Attributes** **Type**
|
|
66
|
-
|
|
67
|
-
*command_detector* instance of pyqt Signal
|
|
68
|
-
*grab_done_signal* instance of pyqt Signal
|
|
69
|
-
*quit_signal* instance of pyqt Signal
|
|
70
|
-
*update_settings_signal* instance of pyqt Signal
|
|
71
|
-
*overshoot_signal* instance of pyqt Signal
|
|
72
|
-
*status_signal* instance of pyqt Signal
|
|
73
|
-
*params* dictionnary list
|
|
74
|
-
|
|
75
|
-
*widgetsettings* instance of QWidget
|
|
76
|
-
*title* string
|
|
77
|
-
*DAQ_type* string
|
|
78
|
-
*dockarea* instance of DockArea
|
|
79
|
-
*bkg* ???
|
|
80
|
-
*filters* instance of tables.Filters
|
|
81
|
-
*settings* instance of pyqtgraph parameter tree
|
|
82
|
-
*measurement_module* ???
|
|
83
|
-
*detector* instance of DAQ_Detector
|
|
84
|
-
*wait_time* int
|
|
85
|
-
*save_file_pathname* string
|
|
86
|
-
*ind_continuous_grab* int
|
|
87
|
-
*initialized_state* boolean
|
|
88
|
-
*snapshot_pathname* string
|
|
89
|
-
*x_axis* 1D numpy array
|
|
90
|
-
*y_axis* 1D numpy array
|
|
91
|
-
*current_datas* dictionnary
|
|
92
|
-
*data_to_save_export* ordered dictionnary
|
|
93
|
-
*do_save_data* boolean
|
|
94
|
-
*do_continuous_save* boolean
|
|
95
|
-
*file_continuous_save* ???
|
|
96
|
-
========================= =======================================
|
|
97
|
-
"""
|
|
98
|
-
command_detector = Signal(ThreadCommand)
|
|
99
|
-
init_signal = Signal(bool)
|
|
100
|
-
custom_sig = Signal(ThreadCommand) # particular case where DAQ_Viewer is used for a custom module
|
|
101
|
-
command_tcpip = Signal(ThreadCommand)
|
|
102
|
-
grab_done_signal = Signal(
|
|
103
|
-
OrderedDict) # OrderedDict(name=self.title,x_axis=None,y_axis=None,z_axis=None,data0D=None,data1D=None,data2D=None)
|
|
104
|
-
quit_signal = Signal()
|
|
105
|
-
update_settings_signal = Signal(edict)
|
|
106
|
-
overshoot_signal = Signal(bool)
|
|
107
|
-
status_signal = Signal(str)
|
|
108
|
-
|
|
109
|
-
params = daq_viewer_params
|
|
110
|
-
|
|
111
|
-
def __init__(self, parent, dock_settings=None, dock_viewer=None, title="Testing", DAQ_type="DAQ0D",
|
|
112
|
-
preset=None, init=False, controller_ID=-1, parent_scan=None):
|
|
113
|
-
|
|
114
|
-
self.logger = utils.set_logger(f'{logger.name}.{title}')
|
|
115
|
-
self.logger.info(f'Initializing DAQ_Viewer: {title}')
|
|
116
|
-
super().__init__()
|
|
117
|
-
|
|
118
|
-
here = Path(__file__).parent
|
|
119
|
-
splash = QtGui.QPixmap(str(here.parent.joinpath('splash.png')))
|
|
120
|
-
self.splash_sc = QtWidgets.QSplashScreen(splash, Qt.WindowStaysOnTopHint)
|
|
121
|
-
self.title = title
|
|
122
|
-
self.DAQ_type = DAQ_type
|
|
123
|
-
self.h5saver_continuous = H5Saver(save_type='detector')
|
|
124
|
-
|
|
125
|
-
self.time_array = None
|
|
126
|
-
self.channel_arrays = []
|
|
127
|
-
self.grab_done = False
|
|
128
|
-
self.start_grab_time = 0. # used for the refreshing rate
|
|
129
|
-
self.navigator = None
|
|
130
|
-
self.scanner = None
|
|
131
|
-
self.received_data = 0
|
|
132
|
-
self.lcd = None
|
|
133
|
-
self.parent_scan = parent_scan # to use if one need the DAQ_Scan object
|
|
134
|
-
|
|
135
|
-
self.ini_time = 0 # used for the continuous saving
|
|
136
|
-
self.wait_time = 1000
|
|
137
|
-
|
|
138
|
-
self.dockarea = parent
|
|
139
|
-
self.bkg = None # buffer to store background
|
|
140
|
-
self.filters = tables.Filters(
|
|
141
|
-
complevel=5) # options to save data to h5 file using compression zlib library and level 5 compression
|
|
142
|
-
|
|
143
|
-
self.send_to_tcpip = False
|
|
144
|
-
self.tcpclient_thread = None
|
|
145
|
-
|
|
146
|
-
self.measurement_module = None
|
|
147
|
-
|
|
148
|
-
self.save_file_pathname = None # to store last active path, will be an Path object
|
|
149
|
-
self.ind_continuous_grab = 0
|
|
150
|
-
|
|
151
|
-
self.initialized_state = False
|
|
152
|
-
self.measurement_module = None
|
|
153
|
-
self.snapshot_pathname = None
|
|
154
|
-
|
|
155
|
-
self.current_datas = None
|
|
156
|
-
# edict to be send to the daq_measurement module from 1D traces if any
|
|
157
|
-
|
|
158
|
-
self.data_to_save_export = None
|
|
159
|
-
|
|
160
|
-
self.do_save_data = False
|
|
161
|
-
self.do_continuous_save = False
|
|
162
|
-
self.is_continuous_initialized = False
|
|
163
|
-
self.file_continuous_save = None
|
|
164
|
-
|
|
165
|
-
# ###########IMPORTANT############################
|
|
166
|
-
self.controller = None
|
|
167
|
-
# the hardware controller/set after initialization and to be used by other modules if needed
|
|
168
|
-
# ################################################
|
|
169
|
-
|
|
170
|
-
self.setupUI(parent, dock_settings, dock_viewer)
|
|
171
|
-
|
|
172
|
-
self.settings.child('main_settings', 'controller_ID').setValue(controller_ID)
|
|
173
|
-
|
|
174
|
-
self.set_enabled_grab_buttons(enable=False)
|
|
175
|
-
self.set_enabled_Ini_buttons(enable=True)
|
|
176
|
-
self.ui.data_ready_led.set_as_false()
|
|
177
|
-
|
|
178
|
-
self.set_setting_tree() # to activate parameters of default Mock detector
|
|
179
|
-
|
|
180
|
-
# set managers options
|
|
181
|
-
if preset is not None:
|
|
182
|
-
for preset_dict in preset:
|
|
183
|
-
# fo instance preset_dict=edict(object='Stage_type_combo',method='setCurrentIndex',value=1)
|
|
184
|
-
if hasattr(self.ui, preset_dict['object']):
|
|
185
|
-
obj = getattr(self.ui, preset_dict['object'])
|
|
186
|
-
if hasattr(obj, preset_dict['method']):
|
|
187
|
-
setattr(obj, preset_dict['method'], preset_dict['value'])
|
|
188
|
-
# initialize the controller if init=True
|
|
189
|
-
if init:
|
|
190
|
-
self.ui.IniDet_pb.click()
|
|
191
|
-
|
|
192
|
-
self.show_settings()
|
|
193
|
-
|
|
194
|
-
@property
|
|
195
|
-
def viewer_docks(self):
|
|
196
|
-
return self.ui.viewer_docks
|
|
197
|
-
|
|
198
|
-
@property
|
|
199
|
-
def daq_type(self):
|
|
200
|
-
return self.ui.DAQ_type_combo.CurrentText()
|
|
201
|
-
|
|
202
|
-
@daq_type.setter
|
|
203
|
-
def daq_type(self, daq_typ):
|
|
204
|
-
self.ui.DAQ_type_combo.setCurrentText(daq_typ)
|
|
205
|
-
|
|
206
|
-
@property
|
|
207
|
-
def detector(self):
|
|
208
|
-
return self.ui.Detector_type_combo.currentText()
|
|
209
|
-
|
|
210
|
-
@detector.setter
|
|
211
|
-
def detector(self, det):
|
|
212
|
-
self.ui.Detector_type_combo.setCurrentText(det)
|
|
213
|
-
if self.detector != det:
|
|
214
|
-
raise DetectorError(f'{det} is not a valid installed detector: {self.detector_types}')
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
@property
|
|
218
|
-
def grab_state(self):
|
|
219
|
-
return self.ui.grab_pb.isChecked()
|
|
220
|
-
|
|
221
|
-
@property
|
|
222
|
-
def is_bkg(self):
|
|
223
|
-
return self.ui.do_bkg_cb.isChecked()
|
|
224
|
-
|
|
225
|
-
@Slot(str)
|
|
226
|
-
def set_DAQ_type(self, daq_type):
|
|
227
|
-
self.DAQ_type = daq_type
|
|
228
|
-
self.settings.child('main_settings', 'DAQ_type').setValue(daq_type)
|
|
229
|
-
|
|
230
|
-
#######################
|
|
231
|
-
# INIT QUIT
|
|
232
|
-
def setupUI(self, parent, dock_settings, dock_viewer):
|
|
233
|
-
self.ui = Ui_Form()
|
|
234
|
-
widgetsettings = QtWidgets.QWidget()
|
|
235
|
-
self.ui.setupUi(widgetsettings)
|
|
236
|
-
|
|
237
|
-
self.ui.title_label.setText(self.title)
|
|
238
|
-
|
|
239
|
-
self.ui.Ini_state_LED.clickable = False
|
|
240
|
-
self.ui.Ini_state_LED.set_as_false()
|
|
241
|
-
|
|
242
|
-
self.ui.navigator_pb.setVisible(False)
|
|
243
|
-
self.ui.navigator_pb.clicked.connect(self.send_to_nav)
|
|
244
|
-
|
|
245
|
-
self.ui.statusbar = QtWidgets.QStatusBar(parent)
|
|
246
|
-
self.ui.statusbar.setMaximumHeight(25)
|
|
247
|
-
self.ui.settings_layout.addWidget(self.ui.statusbar)
|
|
248
|
-
self.ui.status_message = QtWidgets.QLabel()
|
|
249
|
-
self.ui.status_message.setMaximumHeight(25)
|
|
250
|
-
self.ui.statusbar.addWidget(self.ui.status_message)
|
|
251
|
-
|
|
252
|
-
# create main parameter tree
|
|
253
|
-
self.ui.settings_tree = ParameterTree()
|
|
254
|
-
self.ui.settings_layout.addWidget(self.ui.settings_tree, 10)
|
|
255
|
-
self.ui.settings_tree.setMinimumWidth(300)
|
|
256
|
-
self.settings = Parameter.create(title=self.title + ' settings', name='Settings', type='group',
|
|
257
|
-
children=self.params)
|
|
258
|
-
self.settings.child('main_settings', 'DAQ_type').setValue(self.DAQ_type)
|
|
259
|
-
self.ui.settings_tree.setParameters(self.settings, showTop=False)
|
|
260
|
-
self.ui.settings_layout.addWidget(self.h5saver_continuous.settings_tree)
|
|
261
|
-
self.h5saver_continuous.settings_tree.setVisible(False)
|
|
262
|
-
|
|
263
|
-
# connecting from tree
|
|
264
|
-
self.settings.sigTreeStateChanged.connect(
|
|
265
|
-
self.parameter_tree_changed) # any changes on the settings will update accordingly the detector
|
|
266
|
-
self.h5saver_continuous.settings.sigTreeStateChanged.connect(
|
|
267
|
-
self.parameter_tree_changed) # trigger action from "do_save' boolean
|
|
268
|
-
|
|
269
|
-
if dock_settings is not None:
|
|
270
|
-
self.ui.settings_dock = dock_settings
|
|
271
|
-
self.ui.settings_dock.setTitle(self.title + "_Settings")
|
|
272
|
-
else:
|
|
273
|
-
self.ui.settings_dock = Dock(self.title + "_Settings", size=(10, 10))
|
|
274
|
-
self.dockarea.addDock(self.ui.settings_dock)
|
|
275
|
-
|
|
276
|
-
self.ui.viewer_docks = []
|
|
277
|
-
if dock_viewer is not None:
|
|
278
|
-
self.ui.viewer_docks.append(dock_viewer)
|
|
279
|
-
self.ui.viewer_docks[-1].setTitle(self.title + "_Viewer 1")
|
|
280
|
-
else:
|
|
281
|
-
self.ui.viewer_docks.append(Dock(self.title + "_Viewer", size=(500, 300), closable=False))
|
|
282
|
-
self.dockarea.addDock(self.ui.viewer_docks[-1], 'right', self.ui.settings_dock)
|
|
283
|
-
|
|
284
|
-
for dock in self.ui.viewer_docks:
|
|
285
|
-
dock.setEnabled(False)
|
|
286
|
-
|
|
287
|
-
# install specific viewers
|
|
288
|
-
self.viewer_widgets = []
|
|
289
|
-
self.change_viewer()
|
|
290
|
-
|
|
291
|
-
self.ui.settings_dock.addWidget(widgetsettings)
|
|
292
|
-
|
|
293
|
-
# #Setting detector types
|
|
294
|
-
self.ui.Detector_type_combo.clear()
|
|
295
|
-
self.ui.Detector_type_combo.addItems(self.detector_types)
|
|
296
|
-
|
|
297
|
-
# #Connecting buttons:
|
|
298
|
-
self.ui.update_com_pb.clicked.connect(self.update_com) # update communications with hardware
|
|
299
|
-
self.ui.Quit_pb.clicked.connect(self.quit_fun, type=Qt.QueuedConnection)
|
|
300
|
-
self.ui.settings_pb.clicked.connect(self.show_settings)
|
|
301
|
-
self.ui.IniDet_pb.clicked.connect(self.ini_det_fun)
|
|
302
|
-
self.update_status("Ready", wait_time=self.wait_time)
|
|
303
|
-
self.ui.grab_pb.clicked.connect(lambda: self.grab_data(grab_state=True))
|
|
304
|
-
self.ui.single_pb.clicked.connect(lambda: self.grab_data(grab_state=False))
|
|
305
|
-
self.ui.stop_pb.clicked.connect(self.stop_all)
|
|
306
|
-
self.ui.save_new_pb.clicked.connect(self.save_new)
|
|
307
|
-
self.ui.save_current_pb.clicked.connect(self.save_current)
|
|
308
|
-
self.ui.load_data_pb.clicked.connect(self.load_data)
|
|
309
|
-
self.grab_done_signal[OrderedDict].connect(self.save_export_data)
|
|
310
|
-
self.ui.Detector_type_combo.currentIndexChanged.connect(self.set_setting_tree)
|
|
311
|
-
self.ui.save_settings_pb.clicked.connect(self.save_settings)
|
|
312
|
-
self.ui.load_settings_pb.clicked.connect(self.load_settings)
|
|
313
|
-
self.ui.DAQ_type_combo.currentTextChanged[str].connect(self.set_DAQ_type)
|
|
314
|
-
self.ui.take_bkg_cb.clicked.connect(self.take_bkg)
|
|
315
|
-
self.ui.DAQ_type_combo.setCurrentText(self.DAQ_type)
|
|
316
|
-
self.ui.log_pb.clicked.connect(self.show_log)
|
|
317
|
-
|
|
318
|
-
def quit_fun(self):
|
|
319
|
-
"""
|
|
320
|
-
| close the current instance of daq_viewer_main emmiting the quit signal.
|
|
321
|
-
| Treat an exception if an error during the detector unitializing has occured.
|
|
322
|
-
|
|
323
|
-
"""
|
|
324
|
-
# insert anything that needs to be closed before leaving
|
|
325
|
-
try:
|
|
326
|
-
if self.initialized_state: # means initialzed
|
|
327
|
-
self.ui.IniDet_pb.click()
|
|
328
|
-
QtWidgets.QApplication.processEvents()
|
|
329
|
-
self.quit_signal.emit()
|
|
330
|
-
try:
|
|
331
|
-
self.ui.settings_dock.close() # close the settings widget
|
|
332
|
-
except Exception as e:
|
|
333
|
-
self.logger.exception(str(e))
|
|
334
|
-
if self.lcd is not None:
|
|
335
|
-
try:
|
|
336
|
-
self.lcd.parent.close()
|
|
337
|
-
except Exception as e:
|
|
338
|
-
self.logger.exception(str(e))
|
|
339
|
-
try:
|
|
340
|
-
for dock in self.ui.viewer_docks:
|
|
341
|
-
dock.close() # the dock viewers
|
|
342
|
-
except Exception as e:
|
|
343
|
-
self.logger.exception(str(e))
|
|
344
|
-
if hasattr(self, 'nav_dock'):
|
|
345
|
-
self.nav_dock.close()
|
|
346
|
-
|
|
347
|
-
if __name__ == '__main__':
|
|
348
|
-
try:
|
|
349
|
-
self.dockarea.parent().close()
|
|
350
|
-
except Exception as e:
|
|
351
|
-
self.logger.exception(str(e))
|
|
352
|
-
except Exception as e:
|
|
353
|
-
icon = QtGui.QIcon()
|
|
354
|
-
icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/close2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
|
355
|
-
msgBox = QtWidgets.QMessageBox(parent=None)
|
|
356
|
-
msgBox.addButton(QtWidgets.QMessageBox.Yes)
|
|
357
|
-
msgBox.addButton(QtWidgets.QMessageBox.No)
|
|
358
|
-
msgBox.setWindowTitle("Error")
|
|
359
|
-
msgBox.setText(str(e) + " error happened when uninitializing the Detector.\nDo you still want to quit?")
|
|
360
|
-
msgBox.setDefaultButton(QtWidgets.QMessageBox.Yes)
|
|
361
|
-
ret = msgBox.exec()
|
|
362
|
-
if ret == QtWidgets.QMessageBox.Yes:
|
|
363
|
-
self.dockarea.parent().close()
|
|
364
|
-
|
|
365
|
-
def set_enabled_grab_buttons(self, enable=False):
|
|
366
|
-
"""
|
|
367
|
-
Set enable with parameter value :
|
|
368
|
-
* **grab** button
|
|
369
|
-
* **single** button
|
|
370
|
-
* **save current** button
|
|
371
|
-
* **save new** button
|
|
372
|
-
|
|
373
|
-
=============== =========== ===========================
|
|
374
|
-
**Parameters** **Type** **Description**
|
|
375
|
-
enable boolean the default value to map
|
|
376
|
-
=============== =========== ===========================
|
|
377
|
-
"""
|
|
378
|
-
self.ui.grab_pb.setEnabled(enable)
|
|
379
|
-
self.ui.single_pb.setEnabled(enable)
|
|
380
|
-
self.ui.save_current_pb.setEnabled(enable)
|
|
381
|
-
self.ui.save_new_pb.setEnabled(enable)
|
|
382
|
-
# self.ui.settings_pb.setEnabled(enable)
|
|
383
|
-
|
|
384
|
-
def set_enabled_Ini_buttons(self, enable=False):
|
|
385
|
-
"""
|
|
386
|
-
Set enable :
|
|
387
|
-
* **Detector** button
|
|
388
|
-
* **Init Detector** button
|
|
389
|
-
* **Quit** button
|
|
390
|
-
|
|
391
|
-
with the given enable boolean value.
|
|
392
|
-
|
|
393
|
-
=============== =========== ===================
|
|
394
|
-
**Parameters** **Type** **Description**
|
|
395
|
-
*enable* boolean the value to map
|
|
396
|
-
=============== =========== ===================
|
|
397
|
-
"""
|
|
398
|
-
self.ui.Detector_type_combo.setEnabled(enable)
|
|
399
|
-
self.ui.IniDet_pb.setEnabled(enable)
|
|
400
|
-
self.ui.Quit_pb.setEnabled(enable)
|
|
401
|
-
|
|
402
|
-
######################################
|
|
403
|
-
# Methods for running the acquisition
|
|
404
|
-
|
|
405
|
-
def init_det(self):
|
|
406
|
-
self.ui.IniDet_pb.click()
|
|
407
|
-
|
|
408
|
-
def ini_det_fun(self):
|
|
409
|
-
"""
|
|
410
|
-
| If Init detector button checked, init the detector and connect the data detector, the data detector temp, the status and the update_settings signals to their corresponding function.
|
|
411
|
-
| Once done start the detector linked thread.
|
|
412
|
-
|
|
|
413
|
-
| Else send the "close" thread command.
|
|
414
|
-
|
|
415
|
-
See Also
|
|
416
|
-
--------
|
|
417
|
-
set_enabled_grab_buttons, daq_utils.ThreadCommand, DAQ_Detector
|
|
418
|
-
"""
|
|
419
|
-
try:
|
|
420
|
-
QtWidgets.QApplication.processEvents()
|
|
421
|
-
if not self.ui.IniDet_pb.isChecked():
|
|
422
|
-
self.set_enabled_grab_buttons(enable=False)
|
|
423
|
-
self.ui.Ini_state_LED.set_as_false()
|
|
424
|
-
self.initialized_state = False
|
|
425
|
-
|
|
426
|
-
if hasattr(self, 'detector_thread'):
|
|
427
|
-
self.command_detector.emit(ThreadCommand("close"))
|
|
428
|
-
QtWidgets.QApplication.processEvents()
|
|
429
|
-
QThread.msleep(1000)
|
|
430
|
-
if hasattr(self, 'detector_thread'):
|
|
431
|
-
self.detector_thread.quit()
|
|
432
|
-
|
|
433
|
-
self.initialized_state = False
|
|
434
|
-
for dock in self.ui.viewer_docks:
|
|
435
|
-
dock.setEnabled(False)
|
|
436
|
-
|
|
437
|
-
else:
|
|
438
|
-
self.detector_name = self.ui.Detector_type_combo.currentText()
|
|
439
|
-
|
|
440
|
-
detector = DAQ_Detector(self.title, self.settings, self.detector_name)
|
|
441
|
-
self.detector_thread = QThread()
|
|
442
|
-
detector.moveToThread(self.detector_thread)
|
|
443
|
-
|
|
444
|
-
self.command_detector[ThreadCommand].connect(detector.queue_command)
|
|
445
|
-
detector.data_detector_sig[list].connect(self.show_data)
|
|
446
|
-
detector.data_detector_temp_sig[list].connect(self.show_temp_data)
|
|
447
|
-
detector.status_sig[ThreadCommand].connect(self.thread_status)
|
|
448
|
-
self.update_settings_signal[edict].connect(detector.update_settings)
|
|
449
|
-
|
|
450
|
-
self.detector_thread.detector = detector
|
|
451
|
-
self.detector_thread.start()
|
|
452
|
-
|
|
453
|
-
self.command_detector.emit(ThreadCommand("ini_detector", attributes=[
|
|
454
|
-
self.settings.child(('detector_settings')).saveState(), self.controller]))
|
|
455
|
-
|
|
456
|
-
for dock in self.ui.viewer_docks:
|
|
457
|
-
dock.setEnabled(True)
|
|
458
|
-
|
|
459
|
-
except Exception as e:
|
|
460
|
-
self.logger.exception(str(e))
|
|
461
|
-
self.set_enabled_grab_buttons(enable=False)
|
|
462
|
-
|
|
463
|
-
def snap(self):
|
|
464
|
-
self.ui.single_pb.click()
|
|
465
|
-
|
|
466
|
-
def grab(self):
|
|
467
|
-
self.ui.grab_pb.click()
|
|
468
|
-
|
|
469
|
-
def snapshot(self, pathname=None, dosave=False, send_to_tcpip=False):
|
|
470
|
-
"""
|
|
471
|
-
Do one single grab and save the data in pathname.
|
|
472
|
-
|
|
473
|
-
=============== =========== =================================================
|
|
474
|
-
**Parameters** **Type** **Description**
|
|
475
|
-
*pathname* string the pathname to the location os the saved file
|
|
476
|
-
=============== =========== =================================================
|
|
477
|
-
|
|
478
|
-
See Also
|
|
479
|
-
--------
|
|
480
|
-
grab, update_status
|
|
481
|
-
"""
|
|
482
|
-
try:
|
|
483
|
-
self.do_save_data = dosave
|
|
484
|
-
if pathname is None:
|
|
485
|
-
raise (Exception("filepathanme has not been defined in snapshot"))
|
|
486
|
-
self.save_file_pathname = pathname
|
|
487
|
-
|
|
488
|
-
self.grab_data(False, send_to_tcpip=send_to_tcpip)
|
|
489
|
-
except Exception as e:
|
|
490
|
-
self.logger.exception(str(e))
|
|
491
|
-
|
|
492
|
-
def grab_data(self, grab_state=False, send_to_tcpip=False):
|
|
493
|
-
"""
|
|
494
|
-
Do a grab session using 2 profile :
|
|
495
|
-
* if grab pb checked do a continous save and send an "update_channels" thread command and a "grab" too.
|
|
496
|
-
* if not send a "stop_grab" thread command with settings "main settings-naverage" node value as an attribute.
|
|
497
|
-
|
|
498
|
-
See Also
|
|
499
|
-
--------
|
|
500
|
-
daq_utils.ThreadCommand, set_enabled_Ini_buttons
|
|
501
|
-
"""
|
|
502
|
-
self.send_to_tcpip = send_to_tcpip
|
|
503
|
-
self.grab_done = False
|
|
504
|
-
self.ui.data_ready_led.set_as_false()
|
|
505
|
-
self.start_grab_time = time.perf_counter()
|
|
506
|
-
if not (grab_state):
|
|
507
|
-
self.update_status(f'{self.title}: Snap')
|
|
508
|
-
self.command_detector.emit(
|
|
509
|
-
ThreadCommand("single", [self.settings.child('main_settings', 'Naverage').value()]))
|
|
510
|
-
else:
|
|
511
|
-
if not (self.ui.grab_pb.isChecked()):
|
|
512
|
-
|
|
513
|
-
self.update_status(f'{self.title}: Stop Grab')
|
|
514
|
-
self.command_detector.emit(ThreadCommand("stop_grab"))
|
|
515
|
-
self.set_enabled_Ini_buttons(enable=True)
|
|
516
|
-
# self.ui.settings_tree.setEnabled(True)
|
|
517
|
-
else:
|
|
518
|
-
|
|
519
|
-
# self.ui.settings_tree.setEnabled(False)
|
|
520
|
-
self.thread_status(ThreadCommand("update_channels"))
|
|
521
|
-
self.set_enabled_Ini_buttons(enable=False)
|
|
522
|
-
self.update_status(f'{self.title}: Continuous Grab')
|
|
523
|
-
self.command_detector.emit(
|
|
524
|
-
ThreadCommand("grab", [self.settings.child('main_settings', 'Naverage').value()]))
|
|
525
|
-
|
|
526
|
-
def stop_all(self):
|
|
527
|
-
self.update_status(f'{self.title}: Stop Grab')
|
|
528
|
-
self.command_detector.emit(ThreadCommand("stop_all"))
|
|
529
|
-
if self.ui.grab_pb.isChecked():
|
|
530
|
-
self.ui.grab_pb.setChecked(False)
|
|
531
|
-
self.set_enabled_Ini_buttons(enable=True)
|
|
532
|
-
|
|
533
|
-
self.ui.settings_tree.setEnabled(True)
|
|
534
|
-
|
|
535
|
-
def take_bkg(self):
|
|
536
|
-
"""
|
|
537
|
-
Save a new file if bkg check button is on.
|
|
538
|
-
|
|
539
|
-
See Also
|
|
540
|
-
--------
|
|
541
|
-
save_new
|
|
542
|
-
"""
|
|
543
|
-
if self.ui.take_bkg_cb.isChecked():
|
|
544
|
-
self.snap()
|
|
545
|
-
|
|
546
|
-
def stop(self):
|
|
547
|
-
self.ui.stop_pb.click()
|
|
548
|
-
|
|
549
|
-
@Slot()
|
|
550
|
-
def raise_timeout(self):
|
|
551
|
-
"""
|
|
552
|
-
Print the "timeout occured" error message in the status bar via the update_status method.
|
|
553
|
-
|
|
554
|
-
See Also
|
|
555
|
-
--------
|
|
556
|
-
update_status
|
|
557
|
-
"""
|
|
558
|
-
self.update_status("Timeout occured", wait_time=self.wait_time, log_type="log")
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
############ LOADING SAVING
|
|
562
|
-
###########################
|
|
563
|
-
###### LOADING ##########
|
|
564
|
-
|
|
565
|
-
def load_data(self):
|
|
566
|
-
|
|
567
|
-
"""
|
|
568
|
-
|
|
569
|
-
"""
|
|
570
|
-
try:
|
|
571
|
-
data = browse_data()
|
|
572
|
-
datas = [OrderedDict(name='loaded data', data=[data], type='Data2D')]
|
|
573
|
-
self.show_data(datas)
|
|
574
|
-
|
|
575
|
-
except Exception as e:
|
|
576
|
-
self.logger.exception(str(e))
|
|
577
|
-
|
|
578
|
-
def load_settings(self, path=None):
|
|
579
|
-
"""
|
|
580
|
-
to be checked to see if still working
|
|
581
|
-
| Load settings contained in the pathname file (or select_file destination if path not defined).
|
|
582
|
-
| Open a DAQ_type viewer instance (0D, 1D or 2D), send a data_to_save_export signal and restore state from the loaeded settings.
|
|
583
|
-
|
|
584
|
-
=============== ========== =======================================
|
|
585
|
-
**Parameters** **Type** **Description**
|
|
586
|
-
*path* string the pathname of the file to be loaded
|
|
587
|
-
=============== ========== =======================================
|
|
588
|
-
|
|
589
|
-
See Also
|
|
590
|
-
--------
|
|
591
|
-
ini_det_fun, update_status
|
|
592
|
-
"""
|
|
593
|
-
try:
|
|
594
|
-
if self.ui.Ini_state_LED.state: # means initialzed
|
|
595
|
-
self.ui.IniDet_pb.setChecked(False)
|
|
596
|
-
QtWidgets.QApplication.processEvents()
|
|
597
|
-
self.ini_det_fun()
|
|
598
|
-
|
|
599
|
-
if path is None or path is False:
|
|
600
|
-
path = select_file(start_path=Path.home(), save=False, ext='par')
|
|
601
|
-
with open(str(path), 'rb') as f:
|
|
602
|
-
settings = pickle.load(f)
|
|
603
|
-
settings_main = settings['settings_main']
|
|
604
|
-
DAQ_type = settings_main['children']['main_settings']['children']['DAQ_type']['value']
|
|
605
|
-
if DAQ_type != self.settings.child('main_settings', 'DAQ_type'):
|
|
606
|
-
self.settings.child('main_settings', 'DAQ_type').setValue(DAQ_type)
|
|
607
|
-
QtWidgets.QApplication.processEvents()
|
|
608
|
-
|
|
609
|
-
self.settings.restoreState(settings_main)
|
|
610
|
-
|
|
611
|
-
settings_viewer = settings['settings_viewer']
|
|
612
|
-
if self.DAQ_type != 'DAQ0D':
|
|
613
|
-
self.ui.viewers[0].roi_manager.settings.restoreState(settings_viewer)
|
|
614
|
-
|
|
615
|
-
except Exception as e:
|
|
616
|
-
self.logger.exception(str(e))
|
|
617
|
-
|
|
618
|
-
####### SAVING########
|
|
619
|
-
|
|
620
|
-
def set_continuous_save(self):
|
|
621
|
-
"""
|
|
622
|
-
Set a continous save file using the base path located file with
|
|
623
|
-
a header-name containing date as a string.
|
|
624
|
-
|
|
625
|
-
See Also
|
|
626
|
-
--------
|
|
627
|
-
daq_utils.set_current_scan_path
|
|
628
|
-
"""
|
|
629
|
-
if self.h5saver_continuous.settings.child(('do_save')).value():
|
|
630
|
-
self.do_continuous_save = True
|
|
631
|
-
self.is_continuous_initialized = False
|
|
632
|
-
self.h5saver_continuous.settings.child(('base_name')).setValue('Data')
|
|
633
|
-
self.h5saver_continuous.settings.child(('N_saved')).show()
|
|
634
|
-
self.h5saver_continuous.settings.child(('N_saved')).setValue(0)
|
|
635
|
-
self.h5saver_continuous.init_file(update_h5=True)
|
|
636
|
-
|
|
637
|
-
settings_str = ioxml.parameter_to_xml_string(self.settings)
|
|
638
|
-
settings_str = b'<All_settings>' + settings_str
|
|
639
|
-
if hasattr(self.ui.viewers[0], 'roi_manager'):
|
|
640
|
-
settings_str += ioxml.parameter_to_xml_string(self.ui.viewers[0].roi_manager.settings)
|
|
641
|
-
settings_str += ioxml.parameter_to_xml_string(self.h5saver_continuous.settings) + b'</All_settings>'
|
|
642
|
-
self.scan_continuous_group = self.h5saver_continuous.add_scan_group("Continuous Saving")
|
|
643
|
-
self.continuous_group = self.h5saver_continuous.add_det_group(self.scan_continuous_group,
|
|
644
|
-
"Continuous saving", settings_str)
|
|
645
|
-
self.h5saver_continuous.h5_file.flush()
|
|
646
|
-
else:
|
|
647
|
-
self.do_continuous_save = False
|
|
648
|
-
self.h5saver_continuous.settings.child(('N_saved')).hide()
|
|
649
|
-
|
|
650
|
-
try:
|
|
651
|
-
self.h5saver_continuous.close()
|
|
652
|
-
except Exception as e:
|
|
653
|
-
self.logger.exception(str(e))
|
|
654
|
-
|
|
655
|
-
def do_save_continuous(self, datas):
|
|
656
|
-
"""
|
|
657
|
-
method used to perform continuous saving of data, for instance for logging. Will save datas as a function of
|
|
658
|
-
time in a h5 file set when *continuous_saving* parameter as been set.
|
|
659
|
-
|
|
660
|
-
Parameters
|
|
661
|
-
----------
|
|
662
|
-
datas: list of OrderedDict as exported by detector plugins
|
|
663
|
-
|
|
664
|
-
"""
|
|
665
|
-
try:
|
|
666
|
-
# init the enlargeable arrays
|
|
667
|
-
if not self.is_continuous_initialized:
|
|
668
|
-
self.channel_arrays = OrderedDict([])
|
|
669
|
-
self.ini_time = time.perf_counter()
|
|
670
|
-
self.time_array = self.h5saver_continuous.add_navigation_axis(np.array([0.0, ]),
|
|
671
|
-
self.scan_continuous_group, 'x_axis',
|
|
672
|
-
enlargeable=True,
|
|
673
|
-
title='Time axis',
|
|
674
|
-
metadata=dict(nav_index=0,
|
|
675
|
-
label='Time axis',
|
|
676
|
-
units='second'))
|
|
677
|
-
|
|
678
|
-
data_dims = ['data0D', 'data1D']
|
|
679
|
-
if self.h5saver_continuous.settings.child('save_2D').value():
|
|
680
|
-
data_dims.extend(['data2D', 'dataND'])
|
|
681
|
-
|
|
682
|
-
if self.bkg is not None and self.is_bkg:
|
|
683
|
-
bkg_container = OrderedDict([])
|
|
684
|
-
self.process_data(self.bkg, bkg_container)
|
|
685
|
-
|
|
686
|
-
for data_dim in data_dims:
|
|
687
|
-
if data_dim in datas.keys() and len(datas[data_dim]) != 0:
|
|
688
|
-
if not self.h5saver_continuous.is_node_in_group(self.continuous_group, data_dim):
|
|
689
|
-
self.channel_arrays[data_dim] = OrderedDict([])
|
|
690
|
-
|
|
691
|
-
data_group = self.h5saver_continuous.add_data_group(self.continuous_group, data_dim)
|
|
692
|
-
for ind_channel, channel in enumerate(datas[data_dim]): # list of OrderedDict
|
|
693
|
-
|
|
694
|
-
channel_group = self.h5saver_continuous.add_CH_group(data_group, title=channel)
|
|
695
|
-
self.channel_arrays[data_dim]['parent'] = channel_group
|
|
696
|
-
if self.bkg is not None and self.is_bkg:
|
|
697
|
-
if channel in bkg_container[data_dim]:
|
|
698
|
-
datas[data_dim][channel]['bkg'] = bkg_container[data_dim][channel]['data']
|
|
699
|
-
datas[data_dim][channel]['data'] =\
|
|
700
|
-
utils.ensure_ndarray(datas[data_dim][channel]['data'])
|
|
701
|
-
self.channel_arrays[data_dim][channel] = \
|
|
702
|
-
self.h5saver_continuous.add_data(channel_group, datas[data_dim][channel],
|
|
703
|
-
scan_type='scan1D', enlargeable=True)
|
|
704
|
-
self.is_continuous_initialized = True
|
|
705
|
-
|
|
706
|
-
dt = np.array([time.perf_counter() - self.ini_time])
|
|
707
|
-
self.time_array.append(dt)
|
|
708
|
-
|
|
709
|
-
data_dims = ['data0D', 'data1D']
|
|
710
|
-
if self.h5saver_continuous.settings.child('save_2D').value():
|
|
711
|
-
data_dims.extend(['data2D', 'dataND'])
|
|
712
|
-
|
|
713
|
-
for data_dim in data_dims:
|
|
714
|
-
if data_dim in datas.keys() and len(datas[data_dim]) != 0:
|
|
715
|
-
for ind_channel, channel in enumerate(datas[data_dim]):
|
|
716
|
-
if isinstance(datas[data_dim][channel]['data'], float) or isinstance(
|
|
717
|
-
datas[data_dim][channel]['data'], int):
|
|
718
|
-
datas[data_dim][channel]['data'] = np.array([datas[data_dim][channel]['data']])
|
|
719
|
-
self.channel_arrays[data_dim][channel].append(datas[data_dim][channel]['data'])
|
|
720
|
-
|
|
721
|
-
self.h5saver_continuous.h5_file.flush()
|
|
722
|
-
self.h5saver_continuous.settings.child('N_saved').setValue(
|
|
723
|
-
self.h5saver_continuous.settings.child('N_saved').value() + 1)
|
|
724
|
-
|
|
725
|
-
except Exception as e:
|
|
726
|
-
self.logger.exception(str(e))
|
|
727
|
-
|
|
728
|
-
def save_current(self):
|
|
729
|
-
"""
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
See Also
|
|
733
|
-
--------
|
|
734
|
-
gutils.select_file, save_export_data
|
|
735
|
-
"""
|
|
736
|
-
self.do_save_data = True
|
|
737
|
-
self.save_file_pathname = select_file(start_path=self.save_file_pathname, save=True,
|
|
738
|
-
ext='h5') # see daq_utils
|
|
739
|
-
self.save_export_data(self.data_to_save_export)
|
|
740
|
-
|
|
741
|
-
def save_new(self):
|
|
742
|
-
"""
|
|
743
|
-
Do a new save from the select_file obtained pathname into a h5 file structure.
|
|
744
|
-
|
|
745
|
-
See Also
|
|
746
|
-
--------
|
|
747
|
-
gutils.select_file, snapshot
|
|
748
|
-
"""
|
|
749
|
-
self.do_save_data = True
|
|
750
|
-
self.save_file_pathname = select_file(start_path=self.save_file_pathname, save=True,
|
|
751
|
-
ext='h5') # see daq_utils
|
|
752
|
-
self.snapshot(pathname=self.save_file_pathname, dosave=True)
|
|
753
|
-
|
|
754
|
-
def save_datas(self, path=None, datas=None):
|
|
755
|
-
"""
|
|
756
|
-
Save procedure of .h5 file data.
|
|
757
|
-
Course the data array and with :
|
|
758
|
-
* **0D data** : store corresponding datas in a h5 file group (a node of the h5 tree)
|
|
759
|
-
* **1D data** : store corresponding datas in a h5 file group (a node of the h5 tree) with a special array for x_axis values
|
|
760
|
-
* **2D data** : store corresponding datas in a h5 file group (a node of the h5 tree) with a special array for x_axis and y_axis values.
|
|
761
|
-
|
|
762
|
-
=============== ============= ========================================
|
|
763
|
-
**Parameters** **Type** **Description**
|
|
764
|
-
*path* string the path name of the file to be saved.
|
|
765
|
-
*datas* dictionnary the raw datas to save.
|
|
766
|
-
=============== ============= ========================================
|
|
767
|
-
"""
|
|
768
|
-
if path is not None:
|
|
769
|
-
path = Path(path)
|
|
770
|
-
h5saver = H5Saver(save_type='detector')
|
|
771
|
-
h5saver.init_file(update_h5=True, custom_naming=False, addhoc_file_path=path)
|
|
772
|
-
|
|
773
|
-
settings_str = b'<All_settings>' + ioxml.parameter_to_xml_string(self.settings)
|
|
774
|
-
if hasattr(self.ui.viewers[0], 'roi_manager'):
|
|
775
|
-
settings_str += ioxml.parameter_to_xml_string(self.ui.viewers[0].roi_manager.settings)
|
|
776
|
-
settings_str += ioxml.parameter_to_xml_string(h5saver.settings)
|
|
777
|
-
settings_str += b'</All_settings>'
|
|
778
|
-
|
|
779
|
-
det_group = h5saver.add_det_group(h5saver.raw_group, "Data", settings_str)
|
|
780
|
-
if 'external_h5' in datas:
|
|
781
|
-
try:
|
|
782
|
-
external_group = h5saver.add_group('external_data', 'external_h5', det_group)
|
|
783
|
-
if not datas['external_h5'].isopen:
|
|
784
|
-
h5saver = H5Saver()
|
|
785
|
-
h5saver.init_file(addhoc_file_path=datas['external_h5'].filename)
|
|
786
|
-
h5_file = h5saver.h5_file
|
|
787
|
-
else:
|
|
788
|
-
h5_file = datas['external_h5']
|
|
789
|
-
h5_file.copy_children(h5_file.get_node('/'), external_group, recursive=True)
|
|
790
|
-
h5_file.flush()
|
|
791
|
-
h5_file.close()
|
|
792
|
-
|
|
793
|
-
except Exception as e:
|
|
794
|
-
self.logger.exception(str(e))
|
|
795
|
-
try:
|
|
796
|
-
self.channel_arrays = OrderedDict([])
|
|
797
|
-
data_dims = ['data1D'] # we don't recrod 0D data in this mode (only in continuous)
|
|
798
|
-
if h5saver.settings.child(('save_2D')).value():
|
|
799
|
-
data_dims.extend(['data2D', 'dataND'])
|
|
800
|
-
|
|
801
|
-
if self.bkg is not None and self.is_bkg:
|
|
802
|
-
bkg_container = OrderedDict([])
|
|
803
|
-
self.process_data(self.bkg, bkg_container)
|
|
804
|
-
|
|
805
|
-
for data_dim in data_dims:
|
|
806
|
-
if datas[data_dim] is not None:
|
|
807
|
-
if data_dim in datas.keys() and len(datas[data_dim]) != 0:
|
|
808
|
-
if not h5saver.is_node_in_group(det_group, data_dim):
|
|
809
|
-
self.channel_arrays[data_dim] = OrderedDict([])
|
|
810
|
-
|
|
811
|
-
data_group = h5saver.add_data_group(det_group, data_dim)
|
|
812
|
-
for ind_channel, channel in enumerate(datas[data_dim]): # list of OrderedDict
|
|
813
|
-
|
|
814
|
-
channel_group = h5saver.add_CH_group(data_group, title=channel)
|
|
815
|
-
|
|
816
|
-
self.channel_arrays[data_dim]['parent'] = channel_group
|
|
817
|
-
if self.bkg is not None and self.is_bkg:
|
|
818
|
-
if channel in bkg_container[data_dim]:
|
|
819
|
-
datas[data_dim][channel]['bkg'] = bkg_container[data_dim][channel]['data']
|
|
820
|
-
self.channel_arrays[data_dim][channel] = h5saver.add_data(channel_group,
|
|
821
|
-
datas[data_dim][channel],
|
|
822
|
-
scan_type='',
|
|
823
|
-
enlargeable=False)
|
|
824
|
-
|
|
825
|
-
if data_dim == 'data2D' and 'Data2D' in self.viewer_types:
|
|
826
|
-
ind_viewer = self.viewer_types.index('Data2D')
|
|
827
|
-
string = pymodaq.daq_utils.gui_utils.utils.widget_to_png_to_bytes(self.ui.viewers[ind_viewer].parent)
|
|
828
|
-
self.channel_arrays[data_dim][channel].attrs['pixmap2D'] = string
|
|
829
|
-
except Exception as e:
|
|
830
|
-
self.logger.exception(str(e))
|
|
831
|
-
|
|
832
|
-
try:
|
|
833
|
-
(root, filename) = os.path.split(str(path))
|
|
834
|
-
filename, ext = os.path.splitext(filename)
|
|
835
|
-
image_path = os.path.join(root, filename + '.png')
|
|
836
|
-
self.dockarea.parent().grab().save(image_path)
|
|
837
|
-
except Exception as e:
|
|
838
|
-
self.logger.exception(str(e))
|
|
839
|
-
|
|
840
|
-
h5saver.close_file()
|
|
841
|
-
|
|
842
|
-
@Slot(OrderedDict)
|
|
843
|
-
def save_export_data(self, datas):
|
|
844
|
-
"""
|
|
845
|
-
Store in data_to_save_export buffer the data to be saved and do save at self.snapshot_pathname.
|
|
846
|
-
|
|
847
|
-
============== ============= ======================
|
|
848
|
-
**Parameters** **Type** **Description**
|
|
849
|
-
*datas* dictionnary the data to be saved
|
|
850
|
-
============== ============= ======================
|
|
851
|
-
|
|
852
|
-
See Also
|
|
853
|
-
--------
|
|
854
|
-
save_datas
|
|
855
|
-
"""
|
|
856
|
-
|
|
857
|
-
if self.do_save_data:
|
|
858
|
-
self.save_datas(self.save_file_pathname, datas)
|
|
859
|
-
self.do_save_data = False
|
|
860
|
-
|
|
861
|
-
def save_settings(self, path=None):
|
|
862
|
-
"""
|
|
863
|
-
| Save the current viewer settings.
|
|
864
|
-
| In case of Region Of Interest setting, save the current viewer state.
|
|
865
|
-
| Then dump setting if the QDialog has been cancelled.
|
|
866
|
-
|
|
867
|
-
============== ========= ======================================
|
|
868
|
-
**Parameters** **Type** **Description**
|
|
869
|
-
path string the pathname of the file to be saved.
|
|
870
|
-
============== ========= ======================================
|
|
871
|
-
|
|
872
|
-
See Also
|
|
873
|
-
--------
|
|
874
|
-
gutils.select_file, update_status
|
|
875
|
-
"""
|
|
876
|
-
try:
|
|
877
|
-
if path is None or path is False:
|
|
878
|
-
path = select_file(start_path=Path.home(), save=True, ext='par')
|
|
879
|
-
|
|
880
|
-
settings_main = self.settings.saveState()
|
|
881
|
-
if self.DAQ_type != 'DAQ0D':
|
|
882
|
-
settings_viewer = self.ui.viewers[0].roi_manager.settings.saveState()
|
|
883
|
-
else:
|
|
884
|
-
settings_viewer = None
|
|
885
|
-
|
|
886
|
-
settings = OrderedDict(settings_main=settings_main, settings_viewer=settings_viewer)
|
|
887
|
-
|
|
888
|
-
if path is not None: # could be if the Qdialog has been canceled
|
|
889
|
-
with open(str(path), 'wb') as f:
|
|
890
|
-
pickle.dump(settings, f, pickle.HIGHEST_PROTOCOL)
|
|
891
|
-
|
|
892
|
-
except Exception as e:
|
|
893
|
-
self.logger.exception(str(e))
|
|
894
|
-
|
|
895
|
-
######################
|
|
896
|
-
# ### DATAMANAGEMENT
|
|
897
|
-
|
|
898
|
-
@Slot(OrderedDict)
|
|
899
|
-
def get_data_from_viewer(self, datas):
|
|
900
|
-
"""
|
|
901
|
-
Emit the grab done signal with datas as an attribute.
|
|
902
|
-
|
|
903
|
-
=============== ===================== ===================
|
|
904
|
-
**Parameters** **Type** **Description**
|
|
905
|
-
*datas* ordered dictionnary the datas to show
|
|
906
|
-
=============== ===================== ===================
|
|
907
|
-
"""
|
|
908
|
-
# datas=OrderedDict(name=self.title,data0D=None,data1D=None,data2D=None)
|
|
909
|
-
if self.data_to_save_export is not None: # means that somehow datas are not initialized so no further procsessing
|
|
910
|
-
self.received_data += 1
|
|
911
|
-
for key in datas:
|
|
912
|
-
if not (key == 'name' or key == 'acq_time_s'):
|
|
913
|
-
if datas[key] is not None:
|
|
914
|
-
if self.data_to_save_export[key] is None:
|
|
915
|
-
self.data_to_save_export[key] = OrderedDict([])
|
|
916
|
-
for k in datas[key]:
|
|
917
|
-
if datas[key][k]['source'] != 'raw':
|
|
918
|
-
name = f'{self.title}_{datas["name"]}_{k}'
|
|
919
|
-
self.data_to_save_export[key][name] = utils.DataToExport(**datas[key][k])
|
|
920
|
-
# if name not in self.data_to_save_export[key]:
|
|
921
|
-
#
|
|
922
|
-
# self.data_to_save_export[key][name].update(datas[key][k])
|
|
923
|
-
|
|
924
|
-
if self.received_data == len(self.ui.viewers):
|
|
925
|
-
if self.do_continuous_save:
|
|
926
|
-
self.do_save_continuous(self.data_to_save_export)
|
|
927
|
-
|
|
928
|
-
self.grab_done = True
|
|
929
|
-
self.grab_done_signal.emit(self.data_to_save_export)
|
|
930
|
-
|
|
931
|
-
def set_datas_to_viewers(self, datas, temp=False):
|
|
932
|
-
for ind, data in enumerate(datas):
|
|
933
|
-
self.ui.viewers[ind].title = data['name']
|
|
934
|
-
if data['name'] != '':
|
|
935
|
-
self.ui.viewer_docks[ind].setTitle(self.title + ' ' + data['name'])
|
|
936
|
-
if data['dim'].lower() != 'datand':
|
|
937
|
-
self.set_xy_axis(data, ind)
|
|
938
|
-
|
|
939
|
-
if data['dim'] == 'Data0D':
|
|
940
|
-
if 'labels' in data.keys():
|
|
941
|
-
self.ui.viewers[ind].labels = data['labels']
|
|
942
|
-
if temp:
|
|
943
|
-
self.ui.viewers[ind].show_data_temp(data['data'])
|
|
944
|
-
else:
|
|
945
|
-
self.ui.viewers[ind].show_data(data['data'])
|
|
946
|
-
|
|
947
|
-
elif data['dim'] == 'Data1D':
|
|
948
|
-
if 'labels' in data.keys():
|
|
949
|
-
self.ui.viewers[ind].labels = data['labels']
|
|
950
|
-
if temp:
|
|
951
|
-
self.ui.viewers[ind].show_data_temp(data['data'])
|
|
952
|
-
else:
|
|
953
|
-
self.ui.viewers[ind].show_data(data['data'])
|
|
954
|
-
|
|
955
|
-
elif data['dim'] == 'Data2D':
|
|
956
|
-
if temp:
|
|
957
|
-
self.ui.viewers[ind].show_data_temp(data)
|
|
958
|
-
else:
|
|
959
|
-
self.ui.viewers[ind].show_data(data)
|
|
960
|
-
|
|
961
|
-
else:
|
|
962
|
-
if 'nav_axes' in data.keys():
|
|
963
|
-
nav_axes = data['nav_axes']
|
|
964
|
-
else:
|
|
965
|
-
nav_axes = None
|
|
966
|
-
|
|
967
|
-
kwargs = dict()
|
|
968
|
-
if 'nav_x_axis' in data.keys():
|
|
969
|
-
kwargs['nav_x_axis'] = data['nav_x_axis']
|
|
970
|
-
if 'nav_y_axis' in data.keys():
|
|
971
|
-
kwargs['nav_y_axis'] = data['nav_y_axis']
|
|
972
|
-
if 'x_axis' in data.keys():
|
|
973
|
-
kwargs['x_axis'] = data['x_axis']
|
|
974
|
-
if 'y_axis' in data.keys():
|
|
975
|
-
kwargs['y_axis'] = data['y_axis']
|
|
976
|
-
|
|
977
|
-
if isinstance(data['data'], list):
|
|
978
|
-
dat = data['data'][0]
|
|
979
|
-
else:
|
|
980
|
-
dat = data['data']
|
|
981
|
-
|
|
982
|
-
if temp:
|
|
983
|
-
self.ui.viewers[ind].show_data_temp(dat, nav_axes=nav_axes, **kwargs)
|
|
984
|
-
else:
|
|
985
|
-
self.ui.viewers[ind].show_data(dat, nav_axes=nav_axes, **kwargs)
|
|
986
|
-
|
|
987
|
-
def init_show_data(self, datas):
|
|
988
|
-
self.process_overshoot(datas)
|
|
989
|
-
data_dims = [data['dim'] for data in datas]
|
|
990
|
-
if data_dims != self.viewer_types:
|
|
991
|
-
self.update_viewer_pannels(data_dims)
|
|
992
|
-
|
|
993
|
-
def process_data(self, datas, container):
|
|
994
|
-
|
|
995
|
-
data0D = OrderedDict([])
|
|
996
|
-
data1D = OrderedDict([])
|
|
997
|
-
data2D = OrderedDict([])
|
|
998
|
-
dataND = OrderedDict([])
|
|
999
|
-
|
|
1000
|
-
for ind_data, data in enumerate(datas):
|
|
1001
|
-
if 'external_h5' in data.keys():
|
|
1002
|
-
container['external_h5'] = data.pop('external_h5')
|
|
1003
|
-
data_tmp = copy.deepcopy(data)
|
|
1004
|
-
data_dim = data_tmp['dim']
|
|
1005
|
-
if data_dim.lower() != 'datand':
|
|
1006
|
-
self.set_xy_axis(data_tmp, ind_data)
|
|
1007
|
-
data_arrays = data_tmp.pop('data')
|
|
1008
|
-
|
|
1009
|
-
name = data_tmp.pop('name')
|
|
1010
|
-
for ind_sub_data, dat in enumerate(data_arrays):
|
|
1011
|
-
if 'labels' in data_tmp:
|
|
1012
|
-
data_tmp.pop('labels')
|
|
1013
|
-
subdata_tmp = utils.DataToExport(name=self.title, data=dat, **data_tmp)
|
|
1014
|
-
sub_name = f'{self.title}_{name}_CH{ind_sub_data:03}'
|
|
1015
|
-
if data_dim.lower() == 'data0d':
|
|
1016
|
-
subdata_tmp['data'] = subdata_tmp['data'][0]
|
|
1017
|
-
data0D[sub_name] = subdata_tmp
|
|
1018
|
-
elif data_dim.lower() == 'data1d':
|
|
1019
|
-
if 'x_axis' not in subdata_tmp:
|
|
1020
|
-
Nx = len(dat)
|
|
1021
|
-
x_axis = utils.Axis(data=np.linspace(0, Nx - 1, Nx))
|
|
1022
|
-
subdata_tmp['x_axis'] = x_axis
|
|
1023
|
-
data1D[sub_name] = subdata_tmp
|
|
1024
|
-
elif data_dim.lower() == 'data2d':
|
|
1025
|
-
if 'x_axis' not in subdata_tmp:
|
|
1026
|
-
Nx = dat.shape[1]
|
|
1027
|
-
x_axis = utils.Axis(data=np.linspace(0, Nx - 1, Nx))
|
|
1028
|
-
subdata_tmp['x_axis'] = x_axis
|
|
1029
|
-
if 'y_axis' not in subdata_tmp:
|
|
1030
|
-
Ny = dat.shape[0]
|
|
1031
|
-
y_axis = utils.Axis(data=np.linspace(0, Ny - 1, Ny))
|
|
1032
|
-
subdata_tmp['y_axis'] = y_axis
|
|
1033
|
-
data2D[sub_name] = subdata_tmp
|
|
1034
|
-
elif data_dim.lower() == 'datand':
|
|
1035
|
-
dataND[sub_name] = subdata_tmp
|
|
1036
|
-
|
|
1037
|
-
container['data0D'] = data0D
|
|
1038
|
-
container['data1D'] = data1D
|
|
1039
|
-
container['data2D'] = data2D
|
|
1040
|
-
container['dataND'] = dataND
|
|
1041
|
-
|
|
1042
|
-
@Slot(list)
|
|
1043
|
-
def show_data(self, datas: List[utils.DataFromPlugins]):
|
|
1044
|
-
"""
|
|
1045
|
-
|
|
1046
|
-
"""
|
|
1047
|
-
try:
|
|
1048
|
-
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value() and self.send_to_tcpip:
|
|
1049
|
-
self.command_tcpip.emit(ThreadCommand('data_ready', datas))
|
|
1050
|
-
|
|
1051
|
-
self.ui.data_ready_led.set_as_true()
|
|
1052
|
-
self.init_show_data(datas)
|
|
1053
|
-
|
|
1054
|
-
if self.settings.child('main_settings', 'live_averaging').value():
|
|
1055
|
-
self.settings.child('main_settings', 'N_live_averaging').setValue(self.ind_continuous_grab)
|
|
1056
|
-
# #self.ui.current_Naverage.setValue(self.ind_continuous_grab)
|
|
1057
|
-
self.ind_continuous_grab += 1
|
|
1058
|
-
if self.ind_continuous_grab > 1:
|
|
1059
|
-
try:
|
|
1060
|
-
for ind, dic in enumerate(datas):
|
|
1061
|
-
dic['data'] = [((self.ind_continuous_grab - 1) * self.current_datas[ind]['data'][
|
|
1062
|
-
ind_channel] + dic['data'][ind_channel]) / self.ind_continuous_grab for ind_channel in
|
|
1063
|
-
range(len(dic['data']))]
|
|
1064
|
-
except Exception as e:
|
|
1065
|
-
self.logger.exception(str(e))
|
|
1066
|
-
|
|
1067
|
-
# store raw data for further processing
|
|
1068
|
-
Ndatas = len(datas)
|
|
1069
|
-
acq_time = datetime.datetime.now().timestamp()
|
|
1070
|
-
name = self.title
|
|
1071
|
-
self.data_to_save_export = OrderedDict(Ndatas=Ndatas, acq_time_s=acq_time, name=name)
|
|
1072
|
-
|
|
1073
|
-
self.process_data(datas, self.data_to_save_export)
|
|
1074
|
-
|
|
1075
|
-
if self.ui.take_bkg_cb.isChecked():
|
|
1076
|
-
self.ui.take_bkg_cb.setChecked(False)
|
|
1077
|
-
self.bkg = copy.deepcopy(datas)
|
|
1078
|
-
# process bkg if needed
|
|
1079
|
-
if self.is_bkg and self.bkg is not None:
|
|
1080
|
-
try:
|
|
1081
|
-
for ind_channels, channels in enumerate(datas):
|
|
1082
|
-
for ind_channel, channel in enumerate(channels['data']):
|
|
1083
|
-
datas[ind_channels]['data'][ind_channel] -= self.bkg[ind_channels]['data'][ind_channel]
|
|
1084
|
-
except Exception as e:
|
|
1085
|
-
self.logger.exception(str(e))
|
|
1086
|
-
|
|
1087
|
-
if self.ui.grab_pb.isChecked(): # if live
|
|
1088
|
-
refresh = time.perf_counter() - self.start_grab_time > self.settings.child('main_settings',
|
|
1089
|
-
'refresh_time').value() /\
|
|
1090
|
-
1000
|
|
1091
|
-
if refresh:
|
|
1092
|
-
self.start_grab_time = time.perf_counter()
|
|
1093
|
-
else:
|
|
1094
|
-
refresh = True # if single
|
|
1095
|
-
if self.settings.child('main_settings', 'show_data').value() and refresh:
|
|
1096
|
-
self.received_data = 0 # so that data send back from viewers can be properly counted
|
|
1097
|
-
self.set_datas_to_viewers(datas)
|
|
1098
|
-
else:
|
|
1099
|
-
if self.do_continuous_save:
|
|
1100
|
-
self.do_save_continuous(self.data_to_save_export)
|
|
1101
|
-
|
|
1102
|
-
self.grab_done = True
|
|
1103
|
-
self.grab_done_signal.emit(self.data_to_save_export)
|
|
1104
|
-
|
|
1105
|
-
self.current_datas = datas
|
|
1106
|
-
|
|
1107
|
-
except Exception as e:
|
|
1108
|
-
self.logger.exception(str(e))
|
|
1109
|
-
|
|
1110
|
-
@Slot(list)
|
|
1111
|
-
def show_temp_data(self, datas):
|
|
1112
|
-
"""
|
|
1113
|
-
| Show the given datas in the different pannels but do not send processed datas signal.
|
|
1114
|
-
|
|
1115
|
-
=============== ====================== ========================
|
|
1116
|
-
**Parameters** **Type** **Description**
|
|
1117
|
-
datas list of OrderedDict the datas to be showed.
|
|
1118
|
-
=============== ====================== ========================
|
|
1119
|
-
|
|
1120
|
-
"""
|
|
1121
|
-
self.init_show_data(datas)
|
|
1122
|
-
self.set_datas_to_viewers(datas, temp=True)
|
|
1123
|
-
|
|
1124
|
-
@property
|
|
1125
|
-
def viewers(self):
|
|
1126
|
-
return self.ui.viewers
|
|
1127
|
-
|
|
1128
|
-
def update_viewer_pannels(self, data_dims=['Data0D']):
|
|
1129
|
-
Nviewers = len(data_dims)
|
|
1130
|
-
|
|
1131
|
-
self.settings.child('main_settings', 'Nviewers').setValue(Nviewers)
|
|
1132
|
-
|
|
1133
|
-
# check if viewers are compatible with new data type
|
|
1134
|
-
N = 0
|
|
1135
|
-
for ind, data_dim in enumerate(data_dims):
|
|
1136
|
-
if len(self.viewer_types) > ind:
|
|
1137
|
-
if data_dim == self.viewer_types[ind]:
|
|
1138
|
-
N += 1
|
|
1139
|
-
else:
|
|
1140
|
-
break
|
|
1141
|
-
else:
|
|
1142
|
-
break
|
|
1143
|
-
|
|
1144
|
-
while len(self.ui.viewers) > N: # remove all viewers after index N
|
|
1145
|
-
# #while len(self.ui.viewers)>Nviewers:
|
|
1146
|
-
self.ui.viewers.pop()
|
|
1147
|
-
widget = self.viewer_widgets.pop()
|
|
1148
|
-
widget.close()
|
|
1149
|
-
dock = self.ui.viewer_docks.pop()
|
|
1150
|
-
dock.close()
|
|
1151
|
-
QtWidgets.QApplication.processEvents()
|
|
1152
|
-
# #for ind,data_dim in enumerate(data_dims):
|
|
1153
|
-
ind_loop = 0
|
|
1154
|
-
Nviewers_init = len(self.ui.viewers)
|
|
1155
|
-
while len(self.ui.viewers) < len(data_dims):
|
|
1156
|
-
data_dim = data_dims[Nviewers_init + ind_loop]
|
|
1157
|
-
ind_loop += 1
|
|
1158
|
-
if data_dim == "Data0D":
|
|
1159
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1160
|
-
self.ui.viewers.append(Viewer0D(self.viewer_widgets[-1]))
|
|
1161
|
-
elif data_dim == "Data1D":
|
|
1162
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1163
|
-
self.ui.viewers.append(Viewer1D(self.viewer_widgets[-1]))
|
|
1164
|
-
elif data_dim == "Data2D":
|
|
1165
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1166
|
-
self.ui.viewers.append(Viewer2D(self.viewer_widgets[-1]))
|
|
1167
|
-
self.ui.viewers[-1].set_scaling_axes(self.get_scaling_options())
|
|
1168
|
-
self.ui.viewers[-1].get_action('autolevels').trigger()
|
|
1169
|
-
|
|
1170
|
-
else: # for multideimensional data 0 up to dimension 4
|
|
1171
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1172
|
-
self.ui.viewers.append(ViewerND(self.viewer_widgets[-1]))
|
|
1173
|
-
self.ui.viewers[-1].status_signal.connect(self.log_messages)
|
|
1174
|
-
|
|
1175
|
-
self.ui.viewer_docks.append(
|
|
1176
|
-
Dock(self.title + "_Viewer {:d}".format(len(self.ui.viewer_docks) + 1), size=(500, 300),
|
|
1177
|
-
closable=False))
|
|
1178
|
-
self.ui.viewer_docks[-1].addWidget(self.viewer_widgets[-1])
|
|
1179
|
-
if ind == 0:
|
|
1180
|
-
self.dockarea.addDock(self.ui.viewer_docks[-1], 'right', self.ui.settings_dock)
|
|
1181
|
-
else:
|
|
1182
|
-
self.dockarea.addDock(self.ui.viewer_docks[-1], 'right', self.ui.viewer_docks[-2])
|
|
1183
|
-
self.ui.viewers[-1].data_to_export_signal.connect(self.get_data_from_viewer)
|
|
1184
|
-
QtWidgets.QApplication.processEvents()
|
|
1185
|
-
|
|
1186
|
-
self.viewer_types = [viewer.viewer_type for viewer in self.ui.viewers]
|
|
1187
|
-
QtWidgets.QApplication.processEvents()
|
|
1188
|
-
|
|
1189
|
-
#####################
|
|
1190
|
-
##### PROCESS CHANGES
|
|
1191
|
-
#####################
|
|
1192
|
-
|
|
1193
|
-
def log_messages(self, txt):
|
|
1194
|
-
self.status_signal.emit(txt)
|
|
1195
|
-
self.logger.info(txt)
|
|
1196
|
-
|
|
1197
|
-
def update_status(self, txt, wait_time=0, log=True):
|
|
1198
|
-
"""
|
|
1199
|
-
| Show the given txt message in the status bar with a delay of wait_time ms.
|
|
1200
|
-
| Emit a log signal if log_type parameter is defined.
|
|
1201
|
-
|
|
1202
|
-
=============== =========== =====================================
|
|
1203
|
-
**Parameters** **Type** **Description**
|
|
1204
|
-
*txt* string the message to show
|
|
1205
|
-
*wait_time* int the delay of showwing
|
|
1206
|
-
*log_type* string the type of the log signal to emit
|
|
1207
|
-
=============== =========== =====================================
|
|
1208
|
-
"""
|
|
1209
|
-
self.ui.statusbar.showMessage(txt, wait_time)
|
|
1210
|
-
self.status_signal.emit(txt)
|
|
1211
|
-
if log:
|
|
1212
|
-
self.logger.info(txt)
|
|
1213
|
-
|
|
1214
|
-
def parameter_tree_changed(self, param, changes):
|
|
1215
|
-
"""
|
|
1216
|
-
Foreach value changed, update :
|
|
1217
|
-
* Viewer in case of **DAQ_type** parameter name
|
|
1218
|
-
* visibility of button in case of **show_averaging** parameter name
|
|
1219
|
-
* visibility of naverage in case of **live_averaging** parameter name
|
|
1220
|
-
* scale of axis **else** (in 2D pymodaq type)
|
|
1221
|
-
|
|
1222
|
-
Once done emit the update settings signal to link the commit.
|
|
1223
|
-
|
|
1224
|
-
=============== =================================== ================================================================
|
|
1225
|
-
**Parameters** **Type** **Description**
|
|
1226
|
-
*param* instance of ppyqtgraph parameter the parameter to be checked
|
|
1227
|
-
*changes* tuple list Contain the (param,changes,info) list listing the changes made
|
|
1228
|
-
=============== =================================== ================================================================
|
|
1229
|
-
|
|
1230
|
-
See Also
|
|
1231
|
-
--------
|
|
1232
|
-
change_viewer,
|
|
1233
|
-
"""
|
|
1234
|
-
|
|
1235
|
-
for param, change, data in changes:
|
|
1236
|
-
path = self.settings.childPath(param)
|
|
1237
|
-
if change == 'childAdded':
|
|
1238
|
-
if 'main_settings' not in path:
|
|
1239
|
-
self.update_settings_signal.emit(edict(path=path, param=data[0].saveState(), change=change))
|
|
1240
|
-
|
|
1241
|
-
elif change == 'value':
|
|
1242
|
-
if param.name() == 'DAQ_type':
|
|
1243
|
-
self.DAQ_type = param.value()
|
|
1244
|
-
self.change_viewer()
|
|
1245
|
-
self.h5saver_continuous.settings.child('do_save').setValue(False)
|
|
1246
|
-
if param.value() == 'DAQ2D':
|
|
1247
|
-
self.settings.child('main_settings', 'axes').show()
|
|
1248
|
-
else:
|
|
1249
|
-
self.settings.child('main_settings', 'axes').hide()
|
|
1250
|
-
# elif param.name()=='Nviewers': #this parameter is readonly it is updated from the number of items in the data list sent to show_data
|
|
1251
|
-
# self.update_viewer_pannels(param.value())
|
|
1252
|
-
elif param.name() == 'show_averaging':
|
|
1253
|
-
self.settings.child('main_settings', 'live_averaging').setValue(False)
|
|
1254
|
-
self.update_settings_signal.emit(edict(path=path, param=param, change=change))
|
|
1255
|
-
|
|
1256
|
-
elif param.name() == 'live_averaging':
|
|
1257
|
-
self.settings.child('main_settings', 'show_averaging').setValue(False)
|
|
1258
|
-
if param.value():
|
|
1259
|
-
self.settings.child('main_settings', 'N_live_averaging').show()
|
|
1260
|
-
self.ind_continuous_grab = 0
|
|
1261
|
-
self.settings.child('main_settings', 'N_live_averaging').setValue(0)
|
|
1262
|
-
else:
|
|
1263
|
-
self.settings.child('main_settings', 'N_live_averaging').hide()
|
|
1264
|
-
elif param.name() in putils.iter_children(self.settings.child('main_settings', 'axes'), []):
|
|
1265
|
-
if self.DAQ_type == "DAQ2D":
|
|
1266
|
-
if param.name() == 'use_calib':
|
|
1267
|
-
if param.value() != 'None':
|
|
1268
|
-
params = ioxml.XML_file_to_parameter(
|
|
1269
|
-
os.path.join(local_path, 'camera_calibrations', param.value() + '.xml'))
|
|
1270
|
-
param_obj = Parameter.create(name='calib', type='group', children=params)
|
|
1271
|
-
self.settings.child('main_settings', 'axes').restoreState(
|
|
1272
|
-
param_obj.child(('axes')).saveState(), addChildren=False, removeChildren=False)
|
|
1273
|
-
self.settings.child('main_settings', 'axes').show()
|
|
1274
|
-
else:
|
|
1275
|
-
for viewer in self.ui.viewers:
|
|
1276
|
-
viewer.set_scaling_axes(self.get_scaling_options())
|
|
1277
|
-
elif param.name() in putils.iter_children(self.settings.child('detector_settings', 'ROIselect'),
|
|
1278
|
-
[]) and 'ROIselect' in param.parent().name(): # to be sure
|
|
1279
|
-
# a param named 'y0' for instance will not collide with the y0 from the ROI
|
|
1280
|
-
if self.DAQ_type == "DAQ2D":
|
|
1281
|
-
try:
|
|
1282
|
-
self.ui.viewers[0].ROI_select_signal.disconnect(self.update_ROI)
|
|
1283
|
-
except Exception as e:
|
|
1284
|
-
self.logger.exception(str(e))
|
|
1285
|
-
if self.settings.child('detector_settings', 'ROIselect', 'use_ROI').value():
|
|
1286
|
-
if not self.ui.viewers[0].is_action_checked('ROIselect'):
|
|
1287
|
-
self.ui.viewers[0].get_action('ROIselect').trigger()
|
|
1288
|
-
QtWidgets.QApplication.processEvents()
|
|
1289
|
-
self.ui.viewers[0].ROIselect.setPos(
|
|
1290
|
-
self.settings.child('detector_settings', 'ROIselect', 'x0').value(),
|
|
1291
|
-
self.settings.child('detector_settings', 'ROIselect', 'y0').value())
|
|
1292
|
-
self.ui.viewers[0].ROIselect.setSize(
|
|
1293
|
-
[self.settings.child('detector_settings', 'ROIselect', 'width').value(),
|
|
1294
|
-
self.settings.child('detector_settings', 'ROIselect', 'height').value()])
|
|
1295
|
-
self.ui.viewers[0].ROI_select_signal.connect(self.update_ROI)
|
|
1296
|
-
|
|
1297
|
-
elif param.name() == 'continuous_saving_opt':
|
|
1298
|
-
self.h5saver_continuous.settings_tree.setVisible(param.value())
|
|
1299
|
-
|
|
1300
|
-
elif param.name() == 'do_save':
|
|
1301
|
-
self.set_continuous_save()
|
|
1302
|
-
|
|
1303
|
-
elif param.name() == 'wait_time':
|
|
1304
|
-
self.command_detector.emit(ThreadCommand('update_wait_time', [param.value()]))
|
|
1305
|
-
|
|
1306
|
-
elif param.name() == 'connect_server':
|
|
1307
|
-
if param.value():
|
|
1308
|
-
self.connect_tcp_ip()
|
|
1309
|
-
else:
|
|
1310
|
-
self.command_tcpip.emit(ThreadCommand('quit'))
|
|
1311
|
-
|
|
1312
|
-
elif param.name() == 'ip_address' or param.name == 'port':
|
|
1313
|
-
self.command_tcpip.emit(ThreadCommand('update_connection',
|
|
1314
|
-
dict(ipaddress=self.settings.child('main_settings', 'tcpip',
|
|
1315
|
-
'ip_address').value(),
|
|
1316
|
-
port=self.settings.child('main_settings', 'tcpip',
|
|
1317
|
-
'port').value())))
|
|
1318
|
-
|
|
1319
|
-
if path is not None:
|
|
1320
|
-
if 'main_settings' not in path:
|
|
1321
|
-
self.update_settings_signal.emit(edict(path=path, param=param, change=change))
|
|
1322
|
-
|
|
1323
|
-
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value():
|
|
1324
|
-
self.command_tcpip.emit(ThreadCommand('send_info', dict(path=path, param=param)))
|
|
1325
|
-
|
|
1326
|
-
elif change == 'parent':
|
|
1327
|
-
if param.name() not in putils.iter_children(self.settings.child('main_settings'), []):
|
|
1328
|
-
self.update_settings_signal.emit(edict(path=['detector_settings'], param=param, change=change))
|
|
1329
|
-
|
|
1330
|
-
def set_setting_tree(self):
|
|
1331
|
-
"""
|
|
1332
|
-
Set the local setting tree instance cleaning the current one and populate it with
|
|
1333
|
-
standard options corresponding to the pymodaq type viewer (0D, 1D or 2D).
|
|
1334
|
-
|
|
1335
|
-
See Also
|
|
1336
|
-
--------
|
|
1337
|
-
update_status
|
|
1338
|
-
"""
|
|
1339
|
-
det_name = self.detector
|
|
1340
|
-
if det_name == '':
|
|
1341
|
-
det_name = 'Mock'
|
|
1342
|
-
self.detector_name = det_name
|
|
1343
|
-
self.settings.child('main_settings', 'detector_type').setValue(self.detector_name)
|
|
1344
|
-
try:
|
|
1345
|
-
if len(self.settings.child(('detector_settings')).children()) > 0:
|
|
1346
|
-
for child in self.settings.child(('detector_settings')).children()[1:]:
|
|
1347
|
-
# leave just the ROIselect group
|
|
1348
|
-
child.remove()
|
|
1349
|
-
plug_name = self.detector_name
|
|
1350
|
-
if self.DAQ_type == 'DAQ0D':
|
|
1351
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_0DViewer_Det_types, 'name', plug_name)
|
|
1352
|
-
obj = getattr(getattr(parent_module['module'], 'daq_0Dviewer_' + self.detector_name),
|
|
1353
|
-
'DAQ_0DViewer_' + self.detector_name)
|
|
1354
|
-
elif self.DAQ_type == "DAQ1D":
|
|
1355
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_1DViewer_Det_types, 'name', plug_name)
|
|
1356
|
-
obj = getattr(getattr(parent_module['module'], 'daq_1Dviewer_' + self.detector_name),
|
|
1357
|
-
'DAQ_1DViewer_' + self.detector_name)
|
|
1358
|
-
elif self.DAQ_type == 'DAQ2D':
|
|
1359
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_2DViewer_Det_types, 'name', plug_name)
|
|
1360
|
-
obj = getattr(getattr(parent_module['module'], 'daq_2Dviewer_' + self.detector_name),
|
|
1361
|
-
'DAQ_2DViewer_' + self.detector_name)
|
|
1362
|
-
elif self.DAQ_type == 'DAQND':
|
|
1363
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_NDViewer_Det_types, 'name', plug_name)
|
|
1364
|
-
obj = getattr(getattr(parent_module['module'], 'daq_NDviewer_' + self.detector_name),
|
|
1365
|
-
'DAQ_NDViewer_' + self.detector_name)
|
|
1366
|
-
|
|
1367
|
-
params = getattr(obj, 'params')
|
|
1368
|
-
det_params = Parameter.create(name='Det Settings', type='group', children=params)
|
|
1369
|
-
self.settings.child(('detector_settings')).addChildren(det_params.children())
|
|
1370
|
-
except Exception as e:
|
|
1371
|
-
self.logger.exception(str(e))
|
|
1372
|
-
|
|
1373
|
-
def process_overshoot(self, datas):
|
|
1374
|
-
if self.settings.child('main_settings', 'overshoot', 'stop_overshoot').value():
|
|
1375
|
-
for channels in datas:
|
|
1376
|
-
for channel in channels['data']:
|
|
1377
|
-
if any(channel >= self.settings.child('main_settings', 'overshoot', 'overshoot_value').value()):
|
|
1378
|
-
self.overshoot_signal.emit(True)
|
|
1379
|
-
|
|
1380
|
-
def change_viewer(self):
|
|
1381
|
-
"""
|
|
1382
|
-
Change the viewer type from DAQ_Type value between :
|
|
1383
|
-
* **DAQ0D** : a 0D instance of viewer
|
|
1384
|
-
* **DAQ1D** : a 1D instance of viewer
|
|
1385
|
-
* **DAQ2D** : a 2D instance of viewer
|
|
1386
|
-
|
|
1387
|
-
============== ========== ===========================================
|
|
1388
|
-
**Parameters** **Type** **Description**
|
|
1389
|
-
*DAQ_type* string Define the target dimension of the viewer
|
|
1390
|
-
============== ========== ===========================================
|
|
1391
|
-
"""
|
|
1392
|
-
DAQ_type = self.settings.child('main_settings', 'DAQ_type').value()
|
|
1393
|
-
Nviewers = self.settings.child('main_settings', 'Nviewers').value()
|
|
1394
|
-
|
|
1395
|
-
if self.ui.IniDet_pb.isChecked():
|
|
1396
|
-
self.ui.IniDet_pb.click()
|
|
1397
|
-
QtWidgets.QApplication.processEvents()
|
|
1398
|
-
|
|
1399
|
-
self.DAQ_type = DAQ_type
|
|
1400
|
-
if hasattr(self.ui, 'viewers'): # this basically means we are at the initialization satge of the class
|
|
1401
|
-
if self.ui.viewers != []:
|
|
1402
|
-
for ind in range(Nviewers):
|
|
1403
|
-
self.ui.viewers.pop()
|
|
1404
|
-
widget = self.viewer_widgets.pop()
|
|
1405
|
-
widget.close()
|
|
1406
|
-
if len(self.ui.viewer_docks) > 1:
|
|
1407
|
-
dock = self.ui.viewer_docks.pop()
|
|
1408
|
-
dock.close()
|
|
1409
|
-
|
|
1410
|
-
self.ui.viewers = []
|
|
1411
|
-
self.viewer_widgets = []
|
|
1412
|
-
self.viewer_types = []
|
|
1413
|
-
if DAQ_type == "DAQ0D":
|
|
1414
|
-
for ind in range(Nviewers):
|
|
1415
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1416
|
-
self.ui.viewers.append(Viewer0D(self.viewer_widgets[-1]))
|
|
1417
|
-
self.detector_types = [plugin['name'] for plugin in DAQ_0DViewer_Det_types]
|
|
1418
|
-
|
|
1419
|
-
elif DAQ_type == "DAQ1D":
|
|
1420
|
-
for ind in range(Nviewers):
|
|
1421
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1422
|
-
self.ui.viewers.append(Viewer1D(self.viewer_widgets[-1]))
|
|
1423
|
-
self.detector_types = [plugin['name'] for plugin in DAQ_1DViewer_Det_types]
|
|
1424
|
-
|
|
1425
|
-
elif DAQ_type == "DAQ2D":
|
|
1426
|
-
for ind in range(Nviewers):
|
|
1427
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1428
|
-
self.ui.viewers.append(Viewer2D(self.viewer_widgets[-1]))
|
|
1429
|
-
self.ui.viewers[-1].set_scaling_axes(self.get_scaling_options())
|
|
1430
|
-
self.ui.viewers[-1].get_action('autolevels').trigger()
|
|
1431
|
-
|
|
1432
|
-
self.detector_types = [plugin['name'] for plugin in DAQ_2DViewer_Det_types]
|
|
1433
|
-
self.settings.child('main_settings', 'axes').show()
|
|
1434
|
-
self.ui.viewers[0].ROI_select_signal.connect(self.update_ROI)
|
|
1435
|
-
self.ui.viewers[0].get_action('ROIselect').triggered.connect(self.show_ROI)
|
|
1436
|
-
|
|
1437
|
-
elif DAQ_type == "DAQND":
|
|
1438
|
-
for ind in range(Nviewers):
|
|
1439
|
-
self.viewer_widgets.append(QtWidgets.QWidget())
|
|
1440
|
-
self.ui.viewers.append(ViewerND(self.viewer_widgets[-1]))
|
|
1441
|
-
self.detector_types = [plugin['name'] for plugin in DAQ_NDViewer_Det_types]
|
|
1442
|
-
|
|
1443
|
-
self.viewer_types = [viewer.viewer_type for viewer in self.ui.viewers]
|
|
1444
|
-
|
|
1445
|
-
for ind, viewer in enumerate(self.viewer_widgets):
|
|
1446
|
-
if ind == 0:
|
|
1447
|
-
self.dockarea.addDock(self.ui.viewer_docks[-1], 'right', self.ui.settings_dock)
|
|
1448
|
-
else:
|
|
1449
|
-
self.ui.viewer_docks.append(
|
|
1450
|
-
Dock(self.title + "_Viewer {:d}".format(ind), size=(500, 300), closable=False))
|
|
1451
|
-
self.dockarea.addDock(self.ui.viewer_docks[-1], 'right', self.ui.viewer_docks[-2])
|
|
1452
|
-
self.ui.viewer_docks[-1].addWidget(viewer)
|
|
1453
|
-
self.ui.viewers[ind].data_to_export_signal.connect(self.get_data_from_viewer)
|
|
1454
|
-
|
|
1455
|
-
# #Setting detector types
|
|
1456
|
-
try:
|
|
1457
|
-
self.ui.Detector_type_combo.currentIndexChanged.disconnect(self.set_setting_tree)
|
|
1458
|
-
except (TypeError, RuntimeError) as e:
|
|
1459
|
-
pass # just means it wasn't connected yet
|
|
1460
|
-
|
|
1461
|
-
self.ui.Detector_type_combo.clear()
|
|
1462
|
-
self.ui.Detector_type_combo.addItems(self.detector_types)
|
|
1463
|
-
self.ui.Detector_type_combo.currentIndexChanged.connect(self.set_setting_tree)
|
|
1464
|
-
self.set_setting_tree()
|
|
1465
|
-
|
|
1466
|
-
def get_scaling_options(self):
|
|
1467
|
-
"""
|
|
1468
|
-
Return the initialized dictionnary containing the scaling options.
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
Returns
|
|
1472
|
-
-------
|
|
1473
|
-
dictionnary
|
|
1474
|
-
scaling options dictionnary.
|
|
1475
|
-
|
|
1476
|
-
"""
|
|
1477
|
-
scaling_options = utils.ScalingOptions(
|
|
1478
|
-
scaled_xaxis=utils.ScaledAxis(label=self.settings.child('main_settings', 'axes', 'xaxis', 'xlabel').value(),
|
|
1479
|
-
units=self.settings.child('main_settings', 'axes', 'xaxis', 'xunits').value(),
|
|
1480
|
-
offset=self.settings.child('main_settings', 'axes', 'xaxis',
|
|
1481
|
-
'xoffset').value(),
|
|
1482
|
-
scaling=self.settings.child('main_settings', 'axes', 'xaxis',
|
|
1483
|
-
'xscaling').value()),
|
|
1484
|
-
scaled_yaxis=utils.ScaledAxis(label=self.settings.child('main_settings', 'axes', 'yaxis', 'ylabel').value(),
|
|
1485
|
-
units=self.settings.child('main_settings', 'axes', 'yaxis', 'yunits').value(),
|
|
1486
|
-
offset=self.settings.child('main_settings', 'axes', 'yaxis',
|
|
1487
|
-
'yoffset').value(),
|
|
1488
|
-
scaling=self.settings.child('main_settings', 'axes', 'yaxis',
|
|
1489
|
-
'yscaling').value()))
|
|
1490
|
-
return scaling_options
|
|
1491
|
-
|
|
1492
|
-
def set_xy_axis(self, data, ind_viewer):
|
|
1493
|
-
if 'x_axis' in data.keys():
|
|
1494
|
-
self.ui.viewers[ind_viewer].x_axis = data['x_axis']
|
|
1495
|
-
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value():
|
|
1496
|
-
self.command_tcpip.emit(ThreadCommand('x_axis', [data['x_axis']]))
|
|
1497
|
-
|
|
1498
|
-
if 'y_axis' in data.keys():
|
|
1499
|
-
self.ui.viewers[ind_viewer].y_axis = data['y_axis']
|
|
1500
|
-
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value():
|
|
1501
|
-
self.command_tcpip.emit(ThreadCommand('y_axis', [data['y_axis']]))
|
|
1502
|
-
|
|
1503
|
-
def show_settings(self):
|
|
1504
|
-
"""
|
|
1505
|
-
Set the settings tree visible if the corresponding button is checked.
|
|
1506
|
-
"""
|
|
1507
|
-
|
|
1508
|
-
if self.ui.settings_pb.isChecked():
|
|
1509
|
-
self.ui.settings_widget.setVisible(True)
|
|
1510
|
-
else:
|
|
1511
|
-
self.ui.settings_widget.setVisible(False)
|
|
1512
|
-
|
|
1513
|
-
@Slot(ThreadCommand)
|
|
1514
|
-
def thread_status(self, status): # general function to get datas/infos from all threads back to the main
|
|
1515
|
-
"""
|
|
1516
|
-
General function to get datas/infos from all threads back to the main.
|
|
1517
|
-
|
|
1518
|
-
In case of :
|
|
1519
|
-
* **Update_Status** *command* : update the status from the given status attributes
|
|
1520
|
-
* **ini_detector** *command* : update the status with "detector initialized" value and init state if attributes not null.
|
|
1521
|
-
* **close** *command* : close the current thread and delete corresponding attributes on cascade.
|
|
1522
|
-
* **grab** *command* : Do nothing
|
|
1523
|
-
* **x_axis** *command* : update x_axis from status attributes and User Interface viewer consequently.
|
|
1524
|
-
* **y_axis** *command* : update y_axis from status attributes and User Interface viewer consequently.
|
|
1525
|
-
* **Update_channel** *command* : update the viewer channels in case of 0D DAQ_type
|
|
1526
|
-
* **Update_settings** *command* : Update the "detector setting" node in the settings tree.
|
|
1527
|
-
|
|
1528
|
-
=============== ================ =======================================================
|
|
1529
|
-
**Parameters** **Type** **Description**
|
|
1530
|
-
|
|
1531
|
-
*status* ThreadCommand() instance of ThreadCommand containing two attributes:
|
|
1532
|
-
* command : string
|
|
1533
|
-
* attributes: list
|
|
1534
|
-
=============== ================ =======================================================
|
|
1535
|
-
|
|
1536
|
-
See Also
|
|
1537
|
-
--------
|
|
1538
|
-
update_status, set_enabled_grab_buttons, raise_timeout
|
|
1539
|
-
"""
|
|
1540
|
-
if status.command == "Update_Status":
|
|
1541
|
-
if len(status.attributes) > 1:
|
|
1542
|
-
self.update_status(status.attributes[0], wait_time=self.wait_time, log=status.attributes[1])
|
|
1543
|
-
else:
|
|
1544
|
-
self.update_status(status.attributes[0], wait_time=self.wait_time)
|
|
1545
|
-
|
|
1546
|
-
elif status.command == "ini_detector":
|
|
1547
|
-
self.update_status("detector initialized: " + str(status.attributes[0]['initialized']),
|
|
1548
|
-
wait_time=self.wait_time)
|
|
1549
|
-
|
|
1550
|
-
if status.attributes[0]['initialized']:
|
|
1551
|
-
self.controller = status.attributes[0]['controller']
|
|
1552
|
-
self.set_enabled_grab_buttons(enable=True)
|
|
1553
|
-
self.ui.Ini_state_LED.set_as_true()
|
|
1554
|
-
self.initialized_state = True
|
|
1555
|
-
else:
|
|
1556
|
-
self.initialized_state = False
|
|
1557
|
-
self.init_signal.emit(self.initialized_state)
|
|
1558
|
-
|
|
1559
|
-
elif status.command == "close":
|
|
1560
|
-
try:
|
|
1561
|
-
self.update_status(status.attributes[0], wait_time=self.wait_time)
|
|
1562
|
-
self.detector_thread.exit()
|
|
1563
|
-
self.detector_thread.wait()
|
|
1564
|
-
finished = self.detector_thread.isFinished()
|
|
1565
|
-
if finished:
|
|
1566
|
-
delattr(self, 'detector_thread')
|
|
1567
|
-
else:
|
|
1568
|
-
self.update_status('thread is locked?!', self.wait_time, 'log')
|
|
1569
|
-
except Exception as e:
|
|
1570
|
-
self.logger.exception(str(e))
|
|
1571
|
-
|
|
1572
|
-
self.initialized_state = False
|
|
1573
|
-
self.init_signal.emit(self.initialized_state)
|
|
1574
|
-
|
|
1575
|
-
elif status.command == "grab":
|
|
1576
|
-
pass
|
|
1577
|
-
|
|
1578
|
-
elif status.command == "x_axis":
|
|
1579
|
-
try:
|
|
1580
|
-
x_axis = status.attributes[0]
|
|
1581
|
-
if isinstance(x_axis, list):
|
|
1582
|
-
if len(x_axis) == len(self.ui.viewers):
|
|
1583
|
-
for ind, viewer in enumerate(self.ui.viewers):
|
|
1584
|
-
viewer.x_axis = x_axis[ind]
|
|
1585
|
-
x_axis = x_axis[0]
|
|
1586
|
-
else:
|
|
1587
|
-
for viewer in self.ui.viewers:
|
|
1588
|
-
viewer.x_axis = x_axis
|
|
1589
|
-
|
|
1590
|
-
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value():
|
|
1591
|
-
self.command_tcpip.emit(ThreadCommand('x_axis', [x_axis]))
|
|
1592
|
-
|
|
1593
|
-
except Exception as e:
|
|
1594
|
-
self.logger.exception(str(e))
|
|
1595
|
-
|
|
1596
|
-
elif status.command == "y_axis":
|
|
1597
|
-
try:
|
|
1598
|
-
y_axis = status.attributes[0]
|
|
1599
|
-
if isinstance(y_axis, list):
|
|
1600
|
-
if len(y_axis) == len(self.ui.viewers):
|
|
1601
|
-
for ind, viewer in enumerate(self.ui.viewers):
|
|
1602
|
-
viewer.y_axis = y_axis[ind]
|
|
1603
|
-
y_axis = y_axis[0]
|
|
1604
|
-
else:
|
|
1605
|
-
for viewer in self.ui.viewers:
|
|
1606
|
-
viewer.y_axis = y_axis
|
|
1607
|
-
|
|
1608
|
-
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value():
|
|
1609
|
-
self.command_tcpip.emit(ThreadCommand('y_axis', [y_axis]))
|
|
1610
|
-
|
|
1611
|
-
except Exception as e:
|
|
1612
|
-
self.logger.exception(str(e))
|
|
1613
|
-
|
|
1614
|
-
elif status.command == "update_channels":
|
|
1615
|
-
pass
|
|
1616
|
-
# if self.DAQ_type=='DAQ0D':
|
|
1617
|
-
# for viewer in self.ui.viewers:
|
|
1618
|
-
# viewer.update_channels()
|
|
1619
|
-
|
|
1620
|
-
elif status.command == 'update_main_settings':
|
|
1621
|
-
# this is a way for the plugins to update main settings of the ui (solely values, limits and options)
|
|
1622
|
-
try:
|
|
1623
|
-
if status.attributes[2] == 'value':
|
|
1624
|
-
self.settings.child('main_settings', *status.attributes[0]).setValue(status.attributes[1])
|
|
1625
|
-
elif status.attributes[2] == 'limits':
|
|
1626
|
-
self.settings.child('main_settings', *status.attributes[0]).setLimits(status.attributes[1])
|
|
1627
|
-
elif status.attributes[2] == 'options':
|
|
1628
|
-
self.settings.child('main_settings', *status.attributes[0]).setOpts(**status.attributes[1])
|
|
1629
|
-
except Exception as e:
|
|
1630
|
-
self.logger.exception(str(e))
|
|
1631
|
-
|
|
1632
|
-
elif status.command == 'update_settings':
|
|
1633
|
-
# using this the settings shown in the UI for the plugin reflects the real plugin settings
|
|
1634
|
-
try:
|
|
1635
|
-
self.settings.sigTreeStateChanged.disconnect(
|
|
1636
|
-
self.parameter_tree_changed) # any changes on the detcetor settings will update accordingly the gui
|
|
1637
|
-
except Exception as e:
|
|
1638
|
-
self.logger.exception(str(e))
|
|
1639
|
-
try:
|
|
1640
|
-
if status.attributes[2] == 'value':
|
|
1641
|
-
self.settings.child('detector_settings', *status.attributes[0]).setValue(status.attributes[1])
|
|
1642
|
-
elif status.attributes[2] == 'limits':
|
|
1643
|
-
self.settings.child('detector_settings', *status.attributes[0]).setLimits(status.attributes[1])
|
|
1644
|
-
elif status.attributes[2] == 'options':
|
|
1645
|
-
self.settings.child('detector_settings', *status.attributes[0]).setOpts(**status.attributes[1])
|
|
1646
|
-
elif status.attributes[2] == 'childAdded':
|
|
1647
|
-
child = Parameter.create(name='tmp')
|
|
1648
|
-
child.restoreState(status.attributes[1][0])
|
|
1649
|
-
self.settings.child('detector_settings', *status.attributes[0]).addChild(status.attributes[1][0])
|
|
1650
|
-
|
|
1651
|
-
except Exception as e:
|
|
1652
|
-
self.logger.exception(str(e))
|
|
1653
|
-
self.settings.sigTreeStateChanged.connect(self.parameter_tree_changed)
|
|
1654
|
-
|
|
1655
|
-
elif status.command == 'raise_timeout':
|
|
1656
|
-
self.raise_timeout()
|
|
1657
|
-
|
|
1658
|
-
elif status.command == 'show_splash':
|
|
1659
|
-
self.ui.settings_tree.setEnabled(False)
|
|
1660
|
-
self.splash_sc.show()
|
|
1661
|
-
self.splash_sc.raise_()
|
|
1662
|
-
self.splash_sc.showMessage(status.attributes[0], color=Qt.white)
|
|
1663
|
-
|
|
1664
|
-
elif status.command == 'close_splash':
|
|
1665
|
-
self.splash_sc.close()
|
|
1666
|
-
self.ui.settings_tree.setEnabled(True)
|
|
1667
|
-
|
|
1668
|
-
elif status.command == 'init_lcd':
|
|
1669
|
-
if self.lcd is not None:
|
|
1670
|
-
try:
|
|
1671
|
-
self.lcd.parent.close()
|
|
1672
|
-
except Exception as e:
|
|
1673
|
-
self.logger.exception(str(e))
|
|
1674
|
-
# lcd module
|
|
1675
|
-
lcd = QtWidgets.QWidget()
|
|
1676
|
-
self.lcd = LCD(lcd, **status.attributes[0])
|
|
1677
|
-
lcd.setVisible(True)
|
|
1678
|
-
QtWidgets.QApplication.processEvents()
|
|
1679
|
-
|
|
1680
|
-
elif status.command == 'lcd':
|
|
1681
|
-
self.lcd.setvalues(status.attributes[0])
|
|
1682
|
-
|
|
1683
|
-
elif status.command == 'show_navigator':
|
|
1684
|
-
show = True
|
|
1685
|
-
if len(status.attributes) != 0:
|
|
1686
|
-
show = status.attributes[0]
|
|
1687
|
-
self.show_navigator(show)
|
|
1688
|
-
QtWidgets.QApplication.processEvents()
|
|
1689
|
-
|
|
1690
|
-
elif status.command == 'show_scanner':
|
|
1691
|
-
show = True
|
|
1692
|
-
if len(status.attributes) != 0:
|
|
1693
|
-
show = status.attributes[0]
|
|
1694
|
-
self.show_scanner(show)
|
|
1695
|
-
QtWidgets.QApplication.processEvents()
|
|
1696
|
-
|
|
1697
|
-
elif status.command == 'stop':
|
|
1698
|
-
self.stop()
|
|
1699
|
-
|
|
1700
|
-
self.custom_sig.emit(status) # to be used if needed in custom application connected to this module
|
|
1701
|
-
|
|
1702
|
-
def update_com(self):
|
|
1703
|
-
self.command_detector.emit(ThreadCommand('update_com', []))
|
|
1704
|
-
|
|
1705
|
-
@Slot(pymodaq.daq_utils.scanner.ScanParameters)
|
|
1706
|
-
def update_from_scanner(self, scan_parameters):
|
|
1707
|
-
self.command_detector.emit(ThreadCommand('update_scanner', [scan_parameters]))
|
|
1708
|
-
|
|
1709
|
-
def show_ROI(self):
|
|
1710
|
-
if self.DAQ_type == "DAQ2D":
|
|
1711
|
-
self.settings.child('detector_settings', 'ROIselect').setOpts(
|
|
1712
|
-
visible=self.ui.viewers[0].is_action_checked('ROIselect'))
|
|
1713
|
-
pos = self.ui.viewers[0].ROIselect.pos()
|
|
1714
|
-
size = self.ui.viewers[0].ROIselect.size()
|
|
1715
|
-
self.update_ROI(QRectF(pos[0], pos[1], size[0], size[1]))
|
|
1716
|
-
|
|
1717
|
-
@Slot(QRectF)
|
|
1718
|
-
def update_ROI(self, rect=QRectF(0, 0, 1, 1)):
|
|
1719
|
-
if self.DAQ_type == "DAQ2D":
|
|
1720
|
-
self.settings.child('detector_settings', 'ROIselect', 'x0').setValue(int(rect.x()))
|
|
1721
|
-
self.settings.child('detector_settings', 'ROIselect', 'y0').setValue(int(rect.y()))
|
|
1722
|
-
self.settings.child('detector_settings', 'ROIselect', 'width').setValue(max([1, int(rect.width())]))
|
|
1723
|
-
self.settings.child('detector_settings', 'ROIselect', 'height').setValue(max([1, int(rect.height())]))
|
|
1724
|
-
|
|
1725
|
-
######################
|
|
1726
|
-
### EXTERNAL actions
|
|
1727
|
-
|
|
1728
|
-
def send_to_nav(self):
|
|
1729
|
-
datas = dict()
|
|
1730
|
-
keys = list(self.data_to_save_export['data2D'].keys())
|
|
1731
|
-
datas['x_axis'] = self.data_to_save_export['data2D'][keys[0]]['x_axis']
|
|
1732
|
-
datas['y_axis'] = self.data_to_save_export['data2D'][keys[0]]['y_axis']
|
|
1733
|
-
datas['names'] = keys
|
|
1734
|
-
datas['data'] = []
|
|
1735
|
-
for k in self.data_to_save_export['data2D']:
|
|
1736
|
-
datas['data'].append(self.data_to_save_export['data2D'][k]['data'].T)
|
|
1737
|
-
png = self.ui.viewers[0].parent.grab().toImage()
|
|
1738
|
-
png = png.scaled(100, 100, QtCore.Qt.KeepAspectRatio)
|
|
1739
|
-
buffer = QtCore.QBuffer()
|
|
1740
|
-
buffer.open(QtCore.QIODevice.WriteOnly)
|
|
1741
|
-
png.save(buffer, "png")
|
|
1742
|
-
datas['pixmap2D'] = buffer.data().data()
|
|
1743
|
-
|
|
1744
|
-
self.navigator.show_image(datas)
|
|
1745
|
-
|
|
1746
|
-
def show_scanner(self, show=True):
|
|
1747
|
-
if self.scanner is None:
|
|
1748
|
-
items = OrderedDict([])
|
|
1749
|
-
if self.navigator is not None:
|
|
1750
|
-
items['Navigator'] = dict(viewers=[self.navigator.viewer], names=["Navigator"])
|
|
1751
|
-
viewers_title = [view.title for view in self.ui.viewers if view.viewer_type == 'Data2D']
|
|
1752
|
-
if len(viewers_title) > 0:
|
|
1753
|
-
items[self.title] = dict(viewers=[view for view in self.ui.viewers if view.viewer_type == 'Data2D'],
|
|
1754
|
-
names=viewers_title)
|
|
1755
|
-
|
|
1756
|
-
self.scanner = Scanner(items, scan_type='Scan2D')
|
|
1757
|
-
self.scanner.settings_tree.setMinimumHeight(300)
|
|
1758
|
-
self.scanner.settings_tree.setMinimumWidth(300)
|
|
1759
|
-
# self.scanner.settings.child('scan_options', 'scan_type').setValue('Scan2D')
|
|
1760
|
-
# self.scanner.settings.child('scan_options', 'scan2D_settings', 'scan2D_selection').setValue('FromROI')
|
|
1761
|
-
|
|
1762
|
-
# self.navigator.sett_layout.insertWidget(0, self.scanner.settings_tree)
|
|
1763
|
-
self.ui.settings_layout.addWidget(self.scanner.settings_tree)
|
|
1764
|
-
|
|
1765
|
-
QtWidgets.QApplication.processEvents()
|
|
1766
|
-
self.scanner.settings.child('scan_options', 'scan_type').setValue('Scan2D')
|
|
1767
|
-
# self.scanner.settings.child('scan_options', 'scan_type').hide()
|
|
1768
|
-
self.scanner.settings.child('scan_options', 'scan2D_settings', 'scan2D_type').setValue('Linear')
|
|
1769
|
-
# self.scanner.settings.child('scan_options', 'scan2D_settings', 'scan2D_type').hide()
|
|
1770
|
-
self.scanner.scan_params_signal[pymodaq.daq_utils.scanner.ScanParameters].connect(self.update_from_scanner)
|
|
1771
|
-
QtWidgets.QApplication.processEvents()
|
|
1772
|
-
self.scanner.set_scan()
|
|
1773
|
-
|
|
1774
|
-
self.scanner.settings_tree.setVisible(show)
|
|
1775
|
-
|
|
1776
|
-
def show_navigator(self, show=True):
|
|
1777
|
-
if self.navigator is None:
|
|
1778
|
-
self.nav_dock = Dock('Navigator')
|
|
1779
|
-
self.widgnav = QtWidgets.QWidget()
|
|
1780
|
-
self.navigator = Navigator(self.widgnav)
|
|
1781
|
-
self.nav_dock.addWidget(self.widgnav)
|
|
1782
|
-
self.dockarea.addDock(self.nav_dock)
|
|
1783
|
-
self.nav_dock.float()
|
|
1784
|
-
self.navigator.settings.child('settings', 'Load h5').hide()
|
|
1785
|
-
self.navigator.loadaction.setVisible(False)
|
|
1786
|
-
self.navigator.sig_double_clicked.connect(self.move_at_navigator)
|
|
1787
|
-
self.ui.navigator_pb.setVisible(True)
|
|
1788
|
-
|
|
1789
|
-
if self.scanner is not None:
|
|
1790
|
-
items = self.scanner.viewers_items
|
|
1791
|
-
if 'Navigator' not in items:
|
|
1792
|
-
items['Navigator'] = dict(viewers=[self.navigator.viewer], names=["Navigator"])
|
|
1793
|
-
self.scanner.viewers_items = items
|
|
1794
|
-
|
|
1795
|
-
self.widgnav.setVisible(show)
|
|
1796
|
-
|
|
1797
|
-
@Slot(float, float)
|
|
1798
|
-
def move_at_navigator(self, posx, posy):
|
|
1799
|
-
self.command_detector.emit(ThreadCommand("move_at_navigator", [posx, posy]))
|
|
1800
|
-
|
|
1801
|
-
def show_log(self):
|
|
1802
|
-
import webbrowser
|
|
1803
|
-
webbrowser.open(self.logger.parent.handlers[0].baseFilename)
|
|
1804
|
-
|
|
1805
|
-
###########################
|
|
1806
|
-
# TCPIP stuff
|
|
1807
|
-
|
|
1808
|
-
def connect_tcp_ip(self):
|
|
1809
|
-
if self.settings.child('main_settings', 'tcpip', 'connect_server').value():
|
|
1810
|
-
self.tcpclient_thread = QThread()
|
|
1811
|
-
|
|
1812
|
-
tcpclient = TCPClient(self.settings.child('main_settings', 'tcpip', 'ip_address').value(),
|
|
1813
|
-
self.settings.child('main_settings', 'tcpip', 'port').value(),
|
|
1814
|
-
self.settings.child(('detector_settings')))
|
|
1815
|
-
tcpclient.moveToThread(self.tcpclient_thread)
|
|
1816
|
-
self.tcpclient_thread.tcpclient = tcpclient
|
|
1817
|
-
tcpclient.cmd_signal.connect(self.process_tcpip_cmds)
|
|
1818
|
-
|
|
1819
|
-
self.command_tcpip[ThreadCommand].connect(tcpclient.queue_command)
|
|
1820
|
-
|
|
1821
|
-
self.tcpclient_thread.start()
|
|
1822
|
-
tcpclient.init_connection(extra_commands=[ThreadCommand('get_axis')])
|
|
1823
|
-
|
|
1824
|
-
@Slot(ThreadCommand)
|
|
1825
|
-
def process_tcpip_cmds(self, status):
|
|
1826
|
-
if 'Send Data' in status.command:
|
|
1827
|
-
self.snapshot('', send_to_tcpip=True)
|
|
1828
|
-
elif status.command == 'connected':
|
|
1829
|
-
self.settings.child('main_settings', 'tcpip', 'tcp_connected').setValue(True)
|
|
1830
|
-
|
|
1831
|
-
elif status.command == 'disconnected':
|
|
1832
|
-
self.settings.child('main_settings', 'tcpip', 'tcp_connected').setValue(False)
|
|
1833
|
-
|
|
1834
|
-
elif status.command == 'Update_Status':
|
|
1835
|
-
self.thread_status(status)
|
|
1836
|
-
|
|
1837
|
-
elif status.command == 'set_info':
|
|
1838
|
-
param_dict = ioxml.XML_string_to_parameter(status.attributes[1])[0]
|
|
1839
|
-
param_tmp = Parameter.create(**param_dict)
|
|
1840
|
-
param = self.settings.child('detector_settings', *status.attributes[0][1:])
|
|
1841
|
-
|
|
1842
|
-
param.restoreState(param_tmp.saveState())
|
|
1843
|
-
|
|
1844
|
-
elif status.command == 'get_axis':
|
|
1845
|
-
self.command_detector.emit(
|
|
1846
|
-
ThreadCommand('get_axis')) # tells the plugin to emit its axes so that the server will receive them
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
class DAQ_Detector(QObject):
|
|
1850
|
-
"""
|
|
1851
|
-
========================= ==========================
|
|
1852
|
-
**Attributes** **Type**
|
|
1853
|
-
*status_sig* instance of pyqt Signal
|
|
1854
|
-
*data_detector_sig* instance of pyqt Signal
|
|
1855
|
-
*data_detector_temp_sig* instance of pyqt Signal
|
|
1856
|
-
|
|
1857
|
-
*waiting_for_data* boolean
|
|
1858
|
-
*controller* ???
|
|
1859
|
-
*detector_name* string
|
|
1860
|
-
*detector* ???
|
|
1861
|
-
*controller_adress* ???
|
|
1862
|
-
*grab_state* boolean
|
|
1863
|
-
*single_grab* boolean
|
|
1864
|
-
*x_axis* 1D numpy array
|
|
1865
|
-
*y_axis* 1D numpy array
|
|
1866
|
-
*datas* dictionnary
|
|
1867
|
-
*ind_average* int
|
|
1868
|
-
*Naverage* int
|
|
1869
|
-
*average_done* boolean
|
|
1870
|
-
*hardware_averaging* boolean
|
|
1871
|
-
*show_averaging* boolean
|
|
1872
|
-
*wait_time* int
|
|
1873
|
-
*DAQ_type* string
|
|
1874
|
-
========================= ==========================
|
|
1875
|
-
"""
|
|
1876
|
-
status_sig = Signal(ThreadCommand)
|
|
1877
|
-
data_detector_sig = Signal(list)
|
|
1878
|
-
data_detector_temp_sig = Signal(list)
|
|
1879
|
-
|
|
1880
|
-
def __init__(self, title, settings_parameter, detector_name):
|
|
1881
|
-
super().__init__()
|
|
1882
|
-
self.waiting_for_data = False
|
|
1883
|
-
self.controller = None
|
|
1884
|
-
self.logger = utils.set_logger(f'{logger.name}.{title}.detector')
|
|
1885
|
-
self.detector_name = detector_name
|
|
1886
|
-
self.detector = None
|
|
1887
|
-
self.controller_adress = None
|
|
1888
|
-
self.grab_state = False
|
|
1889
|
-
self.single_grab = False
|
|
1890
|
-
self.datas = None
|
|
1891
|
-
self.ind_average = 0
|
|
1892
|
-
self.Naverage = None
|
|
1893
|
-
self.average_done = False
|
|
1894
|
-
self.hardware_averaging = False
|
|
1895
|
-
self.show_averaging = False
|
|
1896
|
-
self.wait_time = settings_parameter.child('main_settings', 'wait_time').value()
|
|
1897
|
-
self.DAQ_type = settings_parameter.child('main_settings', 'DAQ_type').value()
|
|
1898
|
-
|
|
1899
|
-
@Slot(edict)
|
|
1900
|
-
def update_settings(self, settings_parameter_dict):
|
|
1901
|
-
"""
|
|
1902
|
-
| Set attributes values in case of "main_settings" path with corresponding parameter values.
|
|
1903
|
-
| Recursively call the method on detector class attributes else.
|
|
1904
|
-
|
|
1905
|
-
======================== ============== ======================================
|
|
1906
|
-
**Parameters** **Type** **Description**
|
|
1907
|
-
settings_parameter_dict dictionnary the (pathname,parameter) dictionnary
|
|
1908
|
-
======================== ============== ======================================
|
|
1909
|
-
|
|
1910
|
-
See Also
|
|
1911
|
-
--------
|
|
1912
|
-
update_settings
|
|
1913
|
-
"""
|
|
1914
|
-
|
|
1915
|
-
path = settings_parameter_dict['path']
|
|
1916
|
-
param = settings_parameter_dict['param']
|
|
1917
|
-
if path[0] == 'main_settings':
|
|
1918
|
-
if hasattr(self, path[-1]):
|
|
1919
|
-
setattr(self, path[-1], param.value())
|
|
1920
|
-
|
|
1921
|
-
elif path[0] == 'detector_settings':
|
|
1922
|
-
self.detector.update_settings(settings_parameter_dict)
|
|
1923
|
-
|
|
1924
|
-
@Slot(ThreadCommand)
|
|
1925
|
-
def queue_command(self, command=ThreadCommand()):
|
|
1926
|
-
"""
|
|
1927
|
-
Treat the given command parameter from his name :
|
|
1928
|
-
* **ini_detector** : Send the corresponding Thread command via a status signal.
|
|
1929
|
-
* **close** : Send the corresponding Thread command via a status signal.
|
|
1930
|
-
* **grab** : Call the local grab method with command(s) attributes.
|
|
1931
|
-
* **single** : Call the local single method with command(s) attributes.
|
|
1932
|
-
* **stop_grab** : Send the correpsonding Thread command via a status signal.
|
|
1933
|
-
|
|
1934
|
-
=============== ================= ============================
|
|
1935
|
-
**Parameters** *Type* **Description**
|
|
1936
|
-
*command* ThreadCommand() The command to be treated
|
|
1937
|
-
=============== ================= ============================
|
|
1938
|
-
|
|
1939
|
-
See Also
|
|
1940
|
-
--------
|
|
1941
|
-
grab, single, daq_utils.ThreadCommand
|
|
1942
|
-
"""
|
|
1943
|
-
if command.command == "ini_detector":
|
|
1944
|
-
status = self.ini_detector(*command.attributes)
|
|
1945
|
-
self.status_sig.emit(ThreadCommand(command.command, [status, 'log']))
|
|
1946
|
-
|
|
1947
|
-
elif command.command == "close":
|
|
1948
|
-
status = self.close()
|
|
1949
|
-
self.status_sig.emit(ThreadCommand(command.command, [status, 'log']))
|
|
1950
|
-
|
|
1951
|
-
elif command.command == "grab":
|
|
1952
|
-
self.single_grab = False
|
|
1953
|
-
self.grab_state = True
|
|
1954
|
-
self.grab_data(*command.attributes)
|
|
1955
|
-
|
|
1956
|
-
elif command.command == "single":
|
|
1957
|
-
self.single_grab = True
|
|
1958
|
-
self.grab_state = True
|
|
1959
|
-
self.single(*command.attributes)
|
|
1960
|
-
|
|
1961
|
-
elif command.command == "stop_grab":
|
|
1962
|
-
self.grab_state = False
|
|
1963
|
-
# self.status_sig.emit(ThreadCommand("Update_Status", ['Stoping grab']))
|
|
1964
|
-
|
|
1965
|
-
elif command.command == "stop_all":
|
|
1966
|
-
self.grab_state = False
|
|
1967
|
-
self.detector.stop()
|
|
1968
|
-
QtWidgets.QApplication.processEvents()
|
|
1969
|
-
|
|
1970
|
-
elif command.command == 'update_scanner':
|
|
1971
|
-
self.detector.update_scanner(command.attributes[0])
|
|
1972
|
-
|
|
1973
|
-
elif command.command == 'move_at_navigator':
|
|
1974
|
-
self.detector.move_at_navigator(*command.attributes)
|
|
1975
|
-
|
|
1976
|
-
elif command.command == 'update_com':
|
|
1977
|
-
self.detector.update_com()
|
|
1978
|
-
|
|
1979
|
-
elif command.command == 'update_wait_time':
|
|
1980
|
-
self.wait_time = command.attributes[0]
|
|
1981
|
-
|
|
1982
|
-
elif command.command == 'get_axis':
|
|
1983
|
-
self.detector.get_axis()
|
|
1984
|
-
|
|
1985
|
-
else: # custom commands for particular plugins (see spectrometer module 'get_spectro_wl' for instance)
|
|
1986
|
-
if hasattr(self.detector, command.command):
|
|
1987
|
-
cmd = getattr(self.detector, command.command)
|
|
1988
|
-
cmd(*command.attributes)
|
|
1989
|
-
|
|
1990
|
-
def ini_detector(self, params_state=None, controller=None):
|
|
1991
|
-
"""
|
|
1992
|
-
Init the detector from params_state parameter and DAQ_type class attribute :
|
|
1993
|
-
* in **0D** profile : update the local status and send the "x_axis" Thread command via a status signal
|
|
1994
|
-
* in **1D** profile : update the local status and send the "x_axis" Thread command via a status signal
|
|
1995
|
-
* in **2D** profile : update the local status and send the "x_axis" and the "y_axis" Thread command via a status signal
|
|
1996
|
-
|
|
1997
|
-
=============== =========== ==========================================
|
|
1998
|
-
**Parameters** **Type** **Description**
|
|
1999
|
-
*params_state* ??? the parameter's state of initialization
|
|
2000
|
-
=============== =========== ==========================================
|
|
2001
|
-
|
|
2002
|
-
See Also
|
|
2003
|
-
--------
|
|
2004
|
-
ini_detector, daq_utils.ThreadCommand
|
|
2005
|
-
"""
|
|
2006
|
-
try:
|
|
2007
|
-
# status="Not initialized"
|
|
2008
|
-
status = edict(initialized=False, info="", x_axis=None, y_axis=None)
|
|
2009
|
-
|
|
2010
|
-
plug_name = self.detector_name
|
|
2011
|
-
|
|
2012
|
-
if self.DAQ_type == 'DAQ0D':
|
|
2013
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_0DViewer_Det_types, 'name', plug_name)
|
|
2014
|
-
class_ = getattr(getattr(parent_module['module'], 'daq_0Dviewer_' + plug_name),
|
|
2015
|
-
'DAQ_0DViewer_' + plug_name)
|
|
2016
|
-
elif self.DAQ_type == "DAQ1D":
|
|
2017
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_1DViewer_Det_types, 'name', plug_name)
|
|
2018
|
-
class_ = getattr(getattr(parent_module['module'], 'daq_1Dviewer_' + plug_name),
|
|
2019
|
-
'DAQ_1DViewer_' + plug_name)
|
|
2020
|
-
elif self.DAQ_type == 'DAQ2D':
|
|
2021
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_2DViewer_Det_types, 'name', plug_name)
|
|
2022
|
-
class_ = getattr(getattr(parent_module['module'], 'daq_2Dviewer_' + plug_name),
|
|
2023
|
-
'DAQ_2DViewer_' + plug_name)
|
|
2024
|
-
elif self.DAQ_type == 'DAQND':
|
|
2025
|
-
parent_module = utils.find_dict_in_list_from_key_val(DAQ_NDViewer_Det_types, 'name', plug_name)
|
|
2026
|
-
class_ = getattr(getattr(parent_module['module'], 'daq_NDviewer_' + plug_name),
|
|
2027
|
-
'DAQ_NDViewer_' + plug_name)
|
|
2028
|
-
else:
|
|
2029
|
-
raise Exception(plug_name + " unknown")
|
|
2030
|
-
|
|
2031
|
-
self.detector = class_(self, params_state)
|
|
2032
|
-
|
|
2033
|
-
try:
|
|
2034
|
-
self.detector.data_grabed_signal.connect(self.data_ready)
|
|
2035
|
-
self.detector.data_grabed_signal_temp.connect(self.emit_temp_data)
|
|
2036
|
-
infos = self.detector.ini_detector(controller) # return edict(info="", controller=, stage=)
|
|
2037
|
-
except Exception as e:
|
|
2038
|
-
logger.exception('Hardware couldn\'t be initialized' + str(e))
|
|
2039
|
-
infos = str(e), False
|
|
2040
|
-
|
|
2041
|
-
if isinstance(infos, edict):
|
|
2042
|
-
status.update(infos)
|
|
2043
|
-
else:
|
|
2044
|
-
status.info = infos[0]
|
|
2045
|
-
status.initialized = infos[1]
|
|
2046
|
-
|
|
2047
|
-
status.controller = self.detector.controller
|
|
2048
|
-
|
|
2049
|
-
if status['x_axis'] is not None:
|
|
2050
|
-
x_axis = status['x_axis']
|
|
2051
|
-
self.status_sig.emit(ThreadCommand("x_axis", [x_axis]))
|
|
2052
|
-
if status['y_axis'] is not None:
|
|
2053
|
-
y_axis = status['y_axis']
|
|
2054
|
-
self.status_sig.emit(ThreadCommand("y_axis", [y_axis]))
|
|
2055
|
-
|
|
2056
|
-
self.hardware_averaging = class_.hardware_averaging # to check if averaging can be done directly by the hardware or done here software wise
|
|
2057
|
-
|
|
2058
|
-
return status
|
|
2059
|
-
except Exception as e:
|
|
2060
|
-
self.logger.exception(str(e))
|
|
2061
|
-
return status
|
|
2062
|
-
|
|
2063
|
-
@Slot(list)
|
|
2064
|
-
def emit_temp_data(self, datas):
|
|
2065
|
-
self.data_detector_temp_sig.emit(datas)
|
|
2066
|
-
|
|
2067
|
-
@Slot(list)
|
|
2068
|
-
def data_ready(self, datas):
|
|
2069
|
-
"""
|
|
2070
|
-
| Update the local datas attributes from the given datas parameter if the averaging has to be done software wise.
|
|
2071
|
-
|
|
|
2072
|
-
| Else emit the data detector signals with datas parameter as an attribute.
|
|
2073
|
-
|
|
2074
|
-
=============== ===================== =========================
|
|
2075
|
-
**Parameters** **Type** **Description**
|
|
2076
|
-
*datas* list the datas to be emitted.
|
|
2077
|
-
=============== ===================== =========================
|
|
2078
|
-
|
|
2079
|
-
See Also
|
|
2080
|
-
--------
|
|
2081
|
-
daq_utils.ThreadCommand
|
|
2082
|
-
"""
|
|
2083
|
-
|
|
2084
|
-
# datas validation check for backcompatibility with plugins not exporting new DataFromPlugins list of objects
|
|
2085
|
-
|
|
2086
|
-
for dat in datas:
|
|
2087
|
-
if not isinstance(dat, utils.DataFromPlugins):
|
|
2088
|
-
if 'type' in dat:
|
|
2089
|
-
dat['dim'] = dat['type']
|
|
2090
|
-
dat['type'] = 'raw'
|
|
2091
|
-
|
|
2092
|
-
if not self.hardware_averaging: # to execute if the averaging has to be done software wise
|
|
2093
|
-
self.ind_average += 1
|
|
2094
|
-
if self.ind_average == 1:
|
|
2095
|
-
self.datas = datas
|
|
2096
|
-
else:
|
|
2097
|
-
try:
|
|
2098
|
-
for indpannel, dic in enumerate(datas):
|
|
2099
|
-
self.datas[indpannel]['data'] = \
|
|
2100
|
-
[((self.ind_average - 1) * self.datas[indpannel]['data'][ind] + datas[indpannel]['data'][
|
|
2101
|
-
ind]) / self.ind_average for ind in range(len(datas[indpannel]['data']))]
|
|
2102
|
-
|
|
2103
|
-
if self.show_averaging:
|
|
2104
|
-
self.emit_temp_data(self.datas)
|
|
2105
|
-
|
|
2106
|
-
except Exception as e:
|
|
2107
|
-
self.logger.exception(str(e))
|
|
2108
|
-
|
|
2109
|
-
if self.ind_average == self.Naverage:
|
|
2110
|
-
self.average_done = True
|
|
2111
|
-
self.data_detector_sig.emit(self.datas)
|
|
2112
|
-
self.ind_average = 0
|
|
2113
|
-
else:
|
|
2114
|
-
self.data_detector_sig.emit(datas)
|
|
2115
|
-
self.waiting_for_data = False
|
|
2116
|
-
if not self.grab_state:
|
|
2117
|
-
# self.status_sig.emit(["Update_Status","Grabing braked"])
|
|
2118
|
-
self.detector.stop()
|
|
2119
|
-
|
|
2120
|
-
def single(self, Naverage=1, args_as_dict={}):
|
|
2121
|
-
"""
|
|
2122
|
-
Call the grab method with Naverage parameter as an attribute.
|
|
2123
|
-
|
|
2124
|
-
=============== =========== ==================
|
|
2125
|
-
**Parameters** **Type** **Description**
|
|
2126
|
-
*Naverage* int
|
|
2127
|
-
*savepath* str eventual savepath
|
|
2128
|
-
=============== =========== ==================
|
|
2129
|
-
|
|
2130
|
-
See Also
|
|
2131
|
-
--------
|
|
2132
|
-
daq_utils.ThreadCommand, grab
|
|
2133
|
-
"""
|
|
2134
|
-
try:
|
|
2135
|
-
self.grab_data(Naverage, live=False, **args_as_dict)
|
|
2136
|
-
|
|
2137
|
-
except Exception as e:
|
|
2138
|
-
self.logger.exception(str(e))
|
|
2139
|
-
|
|
2140
|
-
def grab_data(self, Naverage=1, live=True, **kwargs):
|
|
2141
|
-
"""
|
|
2142
|
-
| Update status with 'Start Grabing' Update_status sub command of the Thread command.
|
|
2143
|
-
| Process events and grab naverage is needed.
|
|
2144
|
-
|
|
2145
|
-
=============== =========== ==================
|
|
2146
|
-
**Parameters** **Type** **Description**
|
|
2147
|
-
*Naverage* int
|
|
2148
|
-
=============== =========== ==================
|
|
2149
|
-
|
|
2150
|
-
See Also
|
|
2151
|
-
--------
|
|
2152
|
-
daq_utils.ThreadCommand, grab
|
|
2153
|
-
"""
|
|
2154
|
-
try:
|
|
2155
|
-
self.ind_average = 0
|
|
2156
|
-
self.Naverage = Naverage
|
|
2157
|
-
if Naverage > 1:
|
|
2158
|
-
self.average_done = False
|
|
2159
|
-
# self.status_sig.emit(ThreadCommand("Update_Status", [f'Start Grabing']))
|
|
2160
|
-
self.waiting_for_data = False
|
|
2161
|
-
|
|
2162
|
-
# for live mode:two possibilities: either snap one data and regrab softwarewise (while True) or if
|
|
2163
|
-
# self.detector.live_mode_available is True all data is continuously emited from the plugin
|
|
2164
|
-
if self.detector.live_mode_available:
|
|
2165
|
-
kwargs['wait_time'] = self.wait_time
|
|
2166
|
-
else:
|
|
2167
|
-
kwargs['wait_time'] = 0
|
|
2168
|
-
while True:
|
|
2169
|
-
try:
|
|
2170
|
-
if not self.waiting_for_data:
|
|
2171
|
-
self.waiting_for_data = True
|
|
2172
|
-
self.detector.grab_data(Naverage, live=live, **kwargs)
|
|
2173
|
-
QtWidgets.QApplication.processEvents()
|
|
2174
|
-
if self.single_grab:
|
|
2175
|
-
if self.hardware_averaging:
|
|
2176
|
-
break
|
|
2177
|
-
else:
|
|
2178
|
-
if self.average_done:
|
|
2179
|
-
break
|
|
2180
|
-
else:
|
|
2181
|
-
QThread.msleep(self.wait_time) #if in live mode apply a waiting time after acquisition
|
|
2182
|
-
if not self.grab_state:
|
|
2183
|
-
break
|
|
2184
|
-
if self.detector.live_mode_available:
|
|
2185
|
-
break
|
|
2186
|
-
except Exception as e:
|
|
2187
|
-
self.logger.exception(str(e))
|
|
2188
|
-
|
|
2189
|
-
except Exception as e:
|
|
2190
|
-
self.logger.exception(str(e))
|
|
2191
|
-
|
|
2192
|
-
def close(self):
|
|
2193
|
-
"""
|
|
2194
|
-
close the current instance of DAQ_Detector.
|
|
2195
|
-
"""
|
|
2196
|
-
try:
|
|
2197
|
-
status = self.detector.close()
|
|
2198
|
-
except Exception as e:
|
|
2199
|
-
self.logger.exception(str(e))
|
|
2200
|
-
status = str(e)
|
|
2201
|
-
return status
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
def main(init_qt=True):
|
|
2205
|
-
if init_qt: # used for the test suite
|
|
2206
|
-
app = QtWidgets.QApplication(sys.argv)
|
|
2207
|
-
if config('style', 'darkstyle'):
|
|
2208
|
-
import qdarkstyle
|
|
2209
|
-
app.setStyleSheet(qdarkstyle.load_stylesheet(qdarkstyle.DarkPalette))
|
|
2210
|
-
|
|
2211
|
-
win = QtWidgets.QMainWindow()
|
|
2212
|
-
area = DockArea()
|
|
2213
|
-
win.setCentralWidget(area)
|
|
2214
|
-
win.resize(1000, 500)
|
|
2215
|
-
win.setWindowTitle('PyMoDAQ Viewer')
|
|
2216
|
-
viewer = DAQ_Viewer(area, title="Testing", DAQ_type='DAQ2D')
|
|
2217
|
-
win.show()
|
|
2218
|
-
if init_qt:
|
|
2219
|
-
sys.exit(app.exec_())
|
|
2220
|
-
return viewer, win
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
if __name__ == '__main__':
|
|
2224
|
-
|
|
2225
|
-
main()
|