-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScanGUIHelper.py
More file actions
191 lines (158 loc) · 7.2 KB
/
ScanGUIHelper.py
File metadata and controls
191 lines (158 loc) · 7.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
from dataclasses import dataclass, field
from typing import Union
from abc import ABC, abstractmethod
from typing import List, Any, Dict, Tuple
from OCTUiParams import OCTUiParams
#from OCTUi import OCTUi
from VtxEngineParams import VtxEngineParams, AcquisitionType
from vortex.engine import NullEndpoint, VolumeStrobe, SegmentStrobe, SampleStrobe, EventStrobe
from vortex.engine import StackDeviceTensorEndpointInt8, StackHostTensorEndpointInt8, SpectraStackHostTensorEndpointUInt16, SpectraStackEndpoint, NullEndpoint, EventStrobe
from vortex.format import FormatPlanner, StackFormatExecutor
from vortex.storage import SimpleStackUInt16
from qtpy.QtWidgets import QWidget
from vortex import get_console_logger
class ScanGUIHelperComponents:
def __init__(self, format_planner: FormatPlanner, null_endpoint: NullEndpoint, storage_endpoint: SpectraStackEndpoint, spectra_endpoint: SpectraStackHostTensorEndpointUInt16, storage: SimpleStackUInt16, ascan_endpoint: StackDeviceTensorEndpointInt8, plot_widget: QWidget):
self._format_planner = format_planner
self._null_endpoint = null_endpoint
self._storage_endpoint = storage_endpoint
self._storage = storage
self._spectra_endpoint = spectra_endpoint
self._ascan_endpoint = ascan_endpoint
self._plot_widget = plot_widget
@property
def endpoints(self) -> List[Any]:
return [self._null_endpoint, self._storage_endpoint, self._spectra_endpoint, self._ascan_endpoint]
@property
def format_planner(self) -> FormatPlanner:
return self._format_planner
@property
def null_endpoint(self) -> NullEndpoint:
return self._null_endpoint
@property
def storage_endpoint(self) -> SpectraStackEndpoint:
return self._storage_endpoint
@property
def storage(self) -> SimpleStackUInt16:
return self._storage
@property
def spectra_endpoint(self) -> SpectraStackHostTensorEndpointUInt16:
return self._spectra_endpoint
@property
def ascan_endpoint(self) -> StackDeviceTensorEndpointInt8:
return self._ascan_endpoint
@property
def plot_widget(self) -> QWidget:
return self._plot_widget
class ScanGUIHelper(ABC):
'''
ScanGUIHelper is an abstract class used as the bridge between the components of the vortex engine, the specifications for
specific scan types, the plot(s) generated during DAQ, and more. The things created by this class come in two types:
configuration/edit widget, which is used _before_ the engine is started, and the engine components (format planner,
endpoints), which are used when the engine is created.
The edit widget should be created in the constructor, but the components will not be created until createComponents() is called,
with the latest engine parameters as an argument.
'''
def __init__(self, name, flags, params, settings, octui, log_level=1):
'''
Docstring for __init__
:param self: Description
:param name: Name for this scan
:param flags: Bit pattern, will be arg for vortex.marker.Flags()
:param params: Parameters for the helper's edit dialog
:param settings: Settings for this helper's plots (saved range, etc)
:param octui: OCTUi object
:param log_level: Log level for vortex loggers
'''
self.name = name
self.flags = flags
self.params = params
self.settings = settings
self.octui = octui
self.log_level = log_level
self._logger = get_console_logger('GUIHelper({0:s})'.format(self.name))
self._components = None
def has_components(self) -> bool:
return None != self._components
@property
def components(self) -> ScanGUIHelperComponents:
if self._components is None:
raise RuntimeError("Cannot access components before calling createComponents()")
else:
return self._components
@property
def edit_widget(self):
'''
Widget displayed in the editing widget - QStackedWidget. Subclasses should set this.
:param self: Description
'''
return self._edit_widget
def volume(self, arg0: int, arg1: int, arg2: int) -> None:
pass
@abstractmethod
def getScan(self):
'''
Returns a configured scan pattern, e.g. RasterScan
:param self: Description
'''
pass
@abstractmethod
def getParams(self):
"""Return the parameters currently specified in the edit widget"""
pass
@abstractmethod
def getSettings(self) -> dict:
"""Gets settings for plots. Each subclass can decide for itself what settings to save.
Returns:
dict:
"""
pass
@abstractmethod
def clear(self):
"""Clear plots and any internal data
Returns:
None: None
"""
pass
@abstractmethod
def getStrobe(self) -> None|VolumeStrobe|SegmentStrobe|SampleStrobe|EventStrobe:
"""
Return None (if no strobe for this scan type), or return a tuple with the device name and the strobe to use.
The strobe's 'line' parameter should be set here!
:param self: Description
:return: Description
:rtype: None | VolumeStrobe | SegmentStrobe | SampleStrobe | EventStrobe
"""
return None
@abstractmethod
def createEngineComponents(self, octuiparams: OCTUiParams, samples_per_record: int) -> ScanGUIHelperComponents:
'''
Creates SCanGUIHelperComponents using the params passed. The scan params in octuiparams
are the same as the params that this class has, so its OK to use self.params instead of
fishing the params out of octuiparams.scn
:param self: ScanGUIHelper
:param octuiparams: Current engine parameters.
:type octuiparams: OCTUiParams
'''
pass
def _createAscanEndpoint(self, sfe: StackFormatExecutor, shape: Tuple[int, int, int], vtx: VtxEngineParams, logger) -> StackDeviceTensorEndpointInt8 | StackHostTensorEndpointInt8:
'''
Subclasses should call this to get the endpoint for ascans. Checks the acquisition type and returns the
correct endpoint type.
:param self: Description
:param sfe: Stack format executor for this endpoint
:type sfe: StackFormatExecutor
:param shape: Endpoint shape
:type shape: Tuple[int, int, int]
:param vtx: Engine parameters
:type vtx: VtxEngineParams
:param logger: Logger for the endpoint
:return: The endpoint for ascans (post-processing)
:rtype: StackDeviceTensorEndpointInt8 | StackHostTensorEndpointInt8
'''
if vtx.acquisition_type == AcquisitionType.ALAZAR_ACQUISITION:
self._logger.info('Create StackDeviceTensorEndpointInt8 with shape {0:s}'.format(str(shape)))
return StackDeviceTensorEndpointInt8(sfe, shape, logger)
elif vtx.acquisition_type == AcquisitionType.FILE_ACQUISITION:
self._logger.info('Create StackHostTensorEndpointInt8 with shape {0:s}'.format(str(shape)))
return StackHostTensorEndpointInt8(sfe, shape, logger)