microeye 2.3.2__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.
- microEye/__init__.py +47 -0
- microEye/_version.py +2 -0
- microEye/analysis/__init__.py +1 -0
- microEye/analysis/checklist_dialog.py +143 -0
- microEye/analysis/cmosMaps.py +228 -0
- microEye/analysis/filters/__init__.py +9 -0
- microEye/analysis/filters/base.py +21 -0
- microEye/analysis/filters/spatial.py +338 -0
- microEye/analysis/filters/temporal.py +76 -0
- microEye/analysis/fitting/__init__.py +0 -0
- microEye/analysis/fitting/fit.py +680 -0
- microEye/analysis/fitting/nena.py +375 -0
- microEye/analysis/fitting/phasor_fit.py +90 -0
- microEye/analysis/fitting/processing.py +317 -0
- microEye/analysis/fitting/psf/__init__.py +6 -0
- microEye/analysis/fitting/psf/extract.py +1129 -0
- microEye/analysis/fitting/psf/rubost_mean.py +150 -0
- microEye/analysis/fitting/psf/spline.py +167 -0
- microEye/analysis/fitting/psf/stats/__init__.py +12 -0
- microEye/analysis/fitting/psf/stats/core.py +295 -0
- microEye/analysis/fitting/psf/stats/curve_fit.py +708 -0
- microEye/analysis/fitting/psf/stats/io.py +104 -0
- microEye/analysis/fitting/psf/stats/slope_fit.py +171 -0
- microEye/analysis/fitting/psf/temp.py +147 -0
- microEye/analysis/fitting/psf/test.py +47 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUfunctions.py +657 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUmleFit_LM.py +1336 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUsplineLib.py +270 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/__init__.py +1 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUfunctions.py +609 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_EMCCD.py +1396 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_sCMOS.py +1426 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUsplineLib.py +231 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/__init__.py +2 -0
- microEye/analysis/fitting/pyfit3Dcspline/__init__.py +10 -0
- microEye/analysis/fitting/pyfit3Dcspline/constants.py +27 -0
- microEye/analysis/fitting/pyfit3Dcspline/mainfunctions.py +903 -0
- microEye/analysis/fitting/results.py +917 -0
- microEye/analysis/fitting/results_stats.py +251 -0
- microEye/analysis/fitting/tardis.py +209 -0
- microEye/analysis/multi_viewer.py +568 -0
- microEye/analysis/processing/__init__.py +1 -0
- microEye/analysis/processing/frc.py +120 -0
- microEye/analysis/rendering/__init__.py +3 -0
- microEye/analysis/rendering/base.py +452 -0
- microEye/analysis/rendering/cloud.py +215 -0
- microEye/analysis/rendering/core.py +47 -0
- microEye/analysis/rendering/volumetric.py +198 -0
- microEye/analysis/tools/__init__.py +0 -0
- microEye/analysis/tools/kymograms.py +1079 -0
- microEye/analysis/tools/roi_selectors.py +556 -0
- microEye/analysis/utils/__init__.py +3 -0
- microEye/analysis/utils/coordinates.py +18 -0
- microEye/analysis/utils/images.py +68 -0
- microEye/analysis/utils/windows.py +19 -0
- microEye/analysis/viewer/__init__.py +3 -0
- microEye/analysis/viewer/image_options_widget.py +615 -0
- microEye/analysis/viewer/images.py +1225 -0
- microEye/analysis/viewer/layers_widget.py +415 -0
- microEye/analysis/viewer/localizations.py +1304 -0
- microEye/analysis/viewer/psf.py +1003 -0
- microEye/analysis/viewer/volume.py +456 -0
- microEye/hardware/__init__.py +3 -0
- microEye/hardware/cams/__init__.py +29 -0
- microEye/hardware/cams/camera_calibration.py +99 -0
- microEye/hardware/cams/camera_list.py +528 -0
- microEye/hardware/cams/camera_options.py +694 -0
- microEye/hardware/cams/camera_panel.py +941 -0
- microEye/hardware/cams/dummy/__init__.py +1 -0
- microEye/hardware/cams/dummy/dummy_panel.py +759 -0
- microEye/hardware/cams/jobs.py +497 -0
- microEye/hardware/cams/line_profiler.py +99 -0
- microEye/hardware/cams/linescan/IR_Cam.py +474 -0
- microEye/hardware/cams/linescan/__init__.py +1 -0
- microEye/hardware/cams/micam.py +524 -0
- microEye/hardware/cams/pco/__init__.py +58 -0
- microEye/hardware/cams/pco/enums.py +382 -0
- microEye/hardware/cams/pco/pco_cam.py +761 -0
- microEye/hardware/cams/pco/pco_panel.py +477 -0
- microEye/hardware/cams/shortcuts.py +312 -0
- microEye/hardware/cams/thorlabs/__init__.py +1 -0
- microEye/hardware/cams/thorlabs/thorlabs.py +1508 -0
- microEye/hardware/cams/thorlabs/thorlabs_panel.py +850 -0
- microEye/hardware/cams/ueye/__init__.py +1 -0
- microEye/hardware/cams/ueye/ueye_camera.py +1023 -0
- microEye/hardware/cams/ueye/ueye_panel.py +861 -0
- microEye/hardware/cams/vimba/__init__.py +1 -0
- microEye/hardware/cams/vimba/vimba_cam.py +1000 -0
- microEye/hardware/cams/vimba/vimba_panel.py +813 -0
- microEye/hardware/device.py +60 -0
- microEye/hardware/lasers/__init__.py +13 -0
- microEye/hardware/lasers/io_matchbox.py +791 -0
- microEye/hardware/lasers/io_params.py +85 -0
- microEye/hardware/lasers/io_single_laser.py +742 -0
- microEye/hardware/lasers/laser_relay.py +594 -0
- microEye/hardware/mieye/__init__.py +1 -0
- microEye/hardware/mieye/acquisition_manager.py +467 -0
- microEye/hardware/mieye/devices_manager.py +533 -0
- microEye/hardware/mieye/miEye.py +659 -0
- microEye/hardware/misc/__init__.py +0 -0
- microEye/hardware/misc/acquisition_view.py +71 -0
- microEye/hardware/misc/reglo.py +761 -0
- microEye/hardware/misc/temp.py +188 -0
- microEye/hardware/port_config.py +59 -0
- microEye/hardware/protocols/__init__.py +2 -0
- microEye/hardware/protocols/actions.py +402 -0
- microEye/hardware/protocols/actions_items.py +703 -0
- microEye/hardware/protocols/designer.py +244 -0
- microEye/hardware/protocols/scene_manager.py +191 -0
- microEye/hardware/protocols/serialization.py +97 -0
- microEye/hardware/pycromanager/__init__.py +16 -0
- microEye/hardware/pycromanager/core.py +1433 -0
- microEye/hardware/pycromanager/devices.py +461 -0
- microEye/hardware/pycromanager/enums.py +107 -0
- microEye/hardware/pycromanager/headless.py +153 -0
- microEye/hardware/pycromanager/utils.py +34 -0
- microEye/hardware/pycromanager/widgets/__init__.py +5 -0
- microEye/hardware/pycromanager/widgets/bridges.py +407 -0
- microEye/hardware/pycromanager/widgets/headless_manager.py +258 -0
- microEye/hardware/pycromanager/widgets/headless_options.py +224 -0
- microEye/hardware/pycromanager/widgets/pycro_panel.py +455 -0
- microEye/hardware/stages/__init__.py +18 -0
- microEye/hardware/stages/elliptec/__init__.py +5 -0
- microEye/hardware/stages/elliptec/baseDevice.py +314 -0
- microEye/hardware/stages/elliptec/device.py +384 -0
- microEye/hardware/stages/elliptec/deviceID.py +212 -0
- microEye/hardware/stages/elliptec/devicePort.py +379 -0
- microEye/hardware/stages/elliptec/deviceStatus.py +65 -0
- microEye/hardware/stages/elliptec/devicesView.py +706 -0
- microEye/hardware/stages/elliptec/ellDevices.py +134 -0
- microEye/hardware/stages/elliptec/messageUpdater.py +34 -0
- microEye/hardware/stages/elliptec/motorInfo.py +153 -0
- microEye/hardware/stages/elliptec/stage.py +62 -0
- microEye/hardware/stages/elliptec/test.py +139 -0
- microEye/hardware/stages/kinesis/__init__.py +1 -0
- microEye/hardware/stages/kinesis/kdc101/__init__.py +1 -0
- microEye/hardware/stages/kinesis/kdc101/enums.py +1002 -0
- microEye/hardware/stages/kinesis/kdc101/factory.py +171 -0
- microEye/hardware/stages/kinesis/kdc101/kdc101.py +718 -0
- microEye/hardware/stages/kinesis/kinesis.py +776 -0
- microEye/hardware/stages/piezo_concept.py +607 -0
- microEye/hardware/stages/stabilizer.py +785 -0
- microEye/hardware/stages/stage.py +89 -0
- microEye/hardware/widgets/__init__.py +10 -0
- microEye/hardware/widgets/controller.py +246 -0
- microEye/hardware/widgets/devices.py +133 -0
- microEye/hardware/widgets/focusWidget.py +264 -0
- microEye/hardware/widgets/qlist_slider.py +113 -0
- microEye/hardware/widgets/scan_acquisition.py +424 -0
- microEye/icons/1024.png +0 -0
- microEye/icons/128.png +0 -0
- microEye/icons/16.png +0 -0
- microEye/icons/24.png +0 -0
- microEye/icons/256.png +0 -0
- microEye/icons/32.png +0 -0
- microEye/icons/48.png +0 -0
- microEye/icons/512.png +0 -0
- microEye/icons/64.png +0 -0
- microEye/icons/__init__.py +0 -0
- microEye/icons/close.svg +88 -0
- microEye/icons/mieye.png +0 -0
- microEye/icons/min.svg +83 -0
- microEye/icons/viewer.png +0 -0
- microEye/launcher.py +42 -0
- microEye/qt.py +181 -0
- microEye/utils/__init__.py +2 -0
- microEye/utils/enum_encoder.py +10 -0
- microEye/utils/expandable_groupbox.py +93 -0
- microEye/utils/gui_helper.py +457 -0
- microEye/utils/hid/__init__.py +8 -0
- microEye/utils/hid/controller.py +153 -0
- microEye/utils/hid/device.py +63 -0
- microEye/utils/hid/enums.py +140 -0
- microEye/utils/hid/utils.py +58 -0
- microEye/utils/labelled_slider.py +134 -0
- microEye/utils/metadata.py +599 -0
- microEye/utils/metadata_tree.py +718 -0
- microEye/utils/micro_launcher.py +245 -0
- microEye/utils/parameter_tree.py +325 -0
- microEye/utils/pyscripting.py +444 -0
- microEye/utils/retry_exec.py +35 -0
- microEye/utils/start_gui.py +112 -0
- microEye/utils/thread_worker.py +115 -0
- microEye/utils/uImage.py +1512 -0
- microeye-2.3.2.dist-info/METADATA +401 -0
- microeye-2.3.2.dist-info/RECORD +190 -0
- microeye-2.3.2.dist-info/WHEEL +5 -0
- microeye-2.3.2.dist-info/entry_points.txt +2 -0
- microeye-2.3.2.dist-info/licenses/LICENSE +674 -0
- microeye-2.3.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pyqtgraph.parametertree import Parameter
|
|
4
|
+
|
|
5
|
+
from microEye.hardware.lasers.io_params import LaserState, MB_Params
|
|
6
|
+
from microEye.qt import QtCore, QtSerialPort, QtWidgets, Signal
|
|
7
|
+
from microEye.utils import StartGUI, Tree
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class io_combiner(QtSerialPort.QSerialPort):
|
|
11
|
+
'''
|
|
12
|
+
Class representing a laser combiner MatchBox device | Inherits QSerialPort
|
|
13
|
+
'''
|
|
14
|
+
|
|
15
|
+
INFO = b'r i'
|
|
16
|
+
'''Get MatchBox Info
|
|
17
|
+
'''
|
|
18
|
+
ON = b'e 1'
|
|
19
|
+
'''Enable the combiner
|
|
20
|
+
'''
|
|
21
|
+
OFF = b'e 0'
|
|
22
|
+
'''Disable the combiner
|
|
23
|
+
'''
|
|
24
|
+
READ = b'r r'
|
|
25
|
+
SETTINGS = b'r s'
|
|
26
|
+
|
|
27
|
+
ENABLE_1 = b'L1E'
|
|
28
|
+
'''Enable 1st Laser Diode
|
|
29
|
+
'''
|
|
30
|
+
ENABLE_2 = b'L2E'
|
|
31
|
+
'''Enable 2nd Laser Diode
|
|
32
|
+
'''
|
|
33
|
+
ENABLE_3 = b'L3E'
|
|
34
|
+
'''Enable 3rd Laser Diode
|
|
35
|
+
'''
|
|
36
|
+
ENABLE_4 = b'L4E'
|
|
37
|
+
'''Enable 4th Laser Diode
|
|
38
|
+
'''
|
|
39
|
+
DISABLE_1 = b'L1D'
|
|
40
|
+
'''Disable 1st Laser Diode
|
|
41
|
+
'''
|
|
42
|
+
DISABLE_2 = b'L2D'
|
|
43
|
+
'''Disable 2nd Laser Diode
|
|
44
|
+
'''
|
|
45
|
+
DISABLE_3 = b'L3D'
|
|
46
|
+
'''Disable 3rd Laser Diode
|
|
47
|
+
'''
|
|
48
|
+
DISABLE_4 = b'L4D'
|
|
49
|
+
'''Disable 4th Laser Diode
|
|
50
|
+
'''
|
|
51
|
+
|
|
52
|
+
GET_WAVELENGTHS = b'Ln?'
|
|
53
|
+
'''Get available wavelengths
|
|
54
|
+
'''
|
|
55
|
+
|
|
56
|
+
MAX_CUR = b'Lm?'
|
|
57
|
+
'''Get maximum current
|
|
58
|
+
'''
|
|
59
|
+
CUR_SET = b'Lc?'
|
|
60
|
+
'''Get the current set value
|
|
61
|
+
'''
|
|
62
|
+
CUR_CUR = b'Lr'
|
|
63
|
+
'''Get the current reading
|
|
64
|
+
'''
|
|
65
|
+
STATUS = b'Le'
|
|
66
|
+
'''Get the laser diodes enabled(1)/disabled(0) states
|
|
67
|
+
'''
|
|
68
|
+
START = b'c u 2 35488'
|
|
69
|
+
'''TBA
|
|
70
|
+
'''
|
|
71
|
+
|
|
72
|
+
DataReady = Signal(str, bytes)
|
|
73
|
+
|
|
74
|
+
Max_Power = 0.0
|
|
75
|
+
|
|
76
|
+
R_Diode_Temp = 0.0
|
|
77
|
+
R_Crystal_Temp = 0.0
|
|
78
|
+
R_Body_Temp = 0.0
|
|
79
|
+
|
|
80
|
+
R_LD_Current = '0.0mA'
|
|
81
|
+
|
|
82
|
+
R_Crystal_TEC_Load = '0%'
|
|
83
|
+
R_LD_TEC_Load = '0%'
|
|
84
|
+
|
|
85
|
+
R_Status = 'OFF'
|
|
86
|
+
|
|
87
|
+
R_Fan_Load = '0%'
|
|
88
|
+
|
|
89
|
+
R_Input_Voltage = '5V'
|
|
90
|
+
|
|
91
|
+
S_Crystal_Temp = 0.0
|
|
92
|
+
S_Diode_Temp = 0.0
|
|
93
|
+
|
|
94
|
+
S_LD_Current = '0.0mA'
|
|
95
|
+
S_Feedback_DAC = 0
|
|
96
|
+
|
|
97
|
+
S_Power = 0.0
|
|
98
|
+
|
|
99
|
+
S_LD_MaxCurrent = 0.0
|
|
100
|
+
|
|
101
|
+
S_Autostart_Mode = 'OFF'
|
|
102
|
+
|
|
103
|
+
S_Access_Level = 1
|
|
104
|
+
|
|
105
|
+
S_Fan_Temp = 0.0
|
|
106
|
+
|
|
107
|
+
Firmware = ''
|
|
108
|
+
Serial = ''
|
|
109
|
+
Model = ''
|
|
110
|
+
Operation_Time = ''
|
|
111
|
+
ON_Times = ''
|
|
112
|
+
|
|
113
|
+
Current = [0, 0, 0, 0]
|
|
114
|
+
Setting = [0, 0, 0, 0]
|
|
115
|
+
Max = [0, 0, 0, 0]
|
|
116
|
+
Wavelengths = [0, 0, 0, 0]
|
|
117
|
+
|
|
118
|
+
def SendCommand(self, command, log_print: bool = True, delay: int = 1):
|
|
119
|
+
'''Sends a specific command to the device and waits for
|
|
120
|
+
the response then emits the DataReady signal.
|
|
121
|
+
The DataReady signal passes the response and command.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
command : [bytes]
|
|
126
|
+
command to be sent, please check the constants
|
|
127
|
+
implemented in the MatchBox class.
|
|
128
|
+
'''
|
|
129
|
+
if self.isOpen():
|
|
130
|
+
self.readAll()
|
|
131
|
+
self.write(command)
|
|
132
|
+
self.waitForBytesWritten(500)
|
|
133
|
+
QtCore.QThread.msleep(delay)
|
|
134
|
+
while self.bytesAvailable() < 5:
|
|
135
|
+
self.waitForReadyRead(500)
|
|
136
|
+
|
|
137
|
+
response = (
|
|
138
|
+
str(
|
|
139
|
+
self.readAll().replace(b'\xff', b''),
|
|
140
|
+
encoding='utf-8',
|
|
141
|
+
errors='replace',
|
|
142
|
+
)
|
|
143
|
+
.strip('\r\n')
|
|
144
|
+
.strip()
|
|
145
|
+
)
|
|
146
|
+
if log_print:
|
|
147
|
+
print(response, command)
|
|
148
|
+
|
|
149
|
+
self.DataReady.emit(response, command)
|
|
150
|
+
|
|
151
|
+
return response
|
|
152
|
+
|
|
153
|
+
def OpenCOM(self):
|
|
154
|
+
'''Opens the serial port and initializes the combiner.'''
|
|
155
|
+
if not self.isOpen():
|
|
156
|
+
self.open(QtCore.QIODevice.OpenModeFlag.ReadWrite)
|
|
157
|
+
self.flush()
|
|
158
|
+
|
|
159
|
+
if self.isOpen():
|
|
160
|
+
self.SendCommand(io_combiner.ON)
|
|
161
|
+
self.SendCommand(io_combiner.START)
|
|
162
|
+
# self.SendCommand(io_single_laser.STATUS)
|
|
163
|
+
self.GetInfo()
|
|
164
|
+
self.GetWavelengths()
|
|
165
|
+
self.SetCurrent(1, 0)
|
|
166
|
+
self.SetCurrent(2, 0)
|
|
167
|
+
self.SetCurrent(3, 0)
|
|
168
|
+
self.SetCurrent(4, 0)
|
|
169
|
+
self.GetMaxCurrent()
|
|
170
|
+
|
|
171
|
+
def CloseCOM(self):
|
|
172
|
+
'''Closes the serial port.'''
|
|
173
|
+
if self.isOpen():
|
|
174
|
+
self.SendCommand(io_combiner.OFF)
|
|
175
|
+
self.waitForBytesWritten(500)
|
|
176
|
+
|
|
177
|
+
self.close()
|
|
178
|
+
|
|
179
|
+
def GetMaxCurrent(self):
|
|
180
|
+
if self.isOpen():
|
|
181
|
+
res = self.SendCommand(io_combiner.MAX_CUR)
|
|
182
|
+
|
|
183
|
+
if not ('<ERR>' in res or '<ACK>' in res):
|
|
184
|
+
values = res.strip('<').strip('>').split(' ')
|
|
185
|
+
if len(values) >= 4:
|
|
186
|
+
self.Max = list(map(int, values))
|
|
187
|
+
|
|
188
|
+
def GetCurrent(self, log_print: bool = False):
|
|
189
|
+
if self.isOpen():
|
|
190
|
+
res = self.SendCommand(io_combiner.CUR_CUR, log_print)
|
|
191
|
+
|
|
192
|
+
if not ('<ERR>' in res or '<ACK>' in res):
|
|
193
|
+
values = res.strip('<').strip(' mA>').split(' ')
|
|
194
|
+
if len(values) >= 4:
|
|
195
|
+
self.Current = list(map(float, values))
|
|
196
|
+
|
|
197
|
+
def GetSetCurrent(self, log_print: bool = False):
|
|
198
|
+
if self.isOpen():
|
|
199
|
+
res = self.SendCommand(io_combiner.CUR_SET, log_print)
|
|
200
|
+
|
|
201
|
+
if not ('<ERR>' in res or '<ACK>' in res):
|
|
202
|
+
values = res.strip('<').strip('>').split(' ')
|
|
203
|
+
if len(values) >= 4:
|
|
204
|
+
self.Setting = list(map(int, values))
|
|
205
|
+
|
|
206
|
+
def GetWavelengths(self):
|
|
207
|
+
if self.isOpen():
|
|
208
|
+
res = self.SendCommand(io_combiner.GET_WAVELENGTHS)
|
|
209
|
+
|
|
210
|
+
if not ('<ERR>' in res or '<ACK>' in res):
|
|
211
|
+
values = res.strip('<').strip(' >').strip().split(' ')
|
|
212
|
+
self.Wavelengths = []
|
|
213
|
+
if len(values) == 3:
|
|
214
|
+
self.Wavelengths.append(0)
|
|
215
|
+
for x in range(len(values)):
|
|
216
|
+
if values[x].isdigit():
|
|
217
|
+
self.Wavelengths.append(int(values[x]))
|
|
218
|
+
else:
|
|
219
|
+
self.Wavelengths.append(0)
|
|
220
|
+
# if len(values) >= 3:
|
|
221
|
+
# self.Wavelengths = list(map(int, values))
|
|
222
|
+
|
|
223
|
+
def GetReadings(self, log_print: bool = True):
|
|
224
|
+
if self.isOpen():
|
|
225
|
+
res = self.SendCommand(io_combiner.READ, log_print)
|
|
226
|
+
|
|
227
|
+
if not ('<ERR>' in res or '<ACK>' in res):
|
|
228
|
+
readings = res.split(' ')
|
|
229
|
+
if len(readings) >= 10:
|
|
230
|
+
self.R_Diode_Temp = float(readings[1])
|
|
231
|
+
self.R_Crystal_Temp = float(readings[2])
|
|
232
|
+
self.R_Body_Temp = float(readings[3])
|
|
233
|
+
self.R_LD_Current = readings[4]
|
|
234
|
+
self.R_Crystal_TEC_Load = readings[5]
|
|
235
|
+
self.R_LD_TEC_Load = readings[6]
|
|
236
|
+
self.R_Status = readings[7]
|
|
237
|
+
self.R_Fan_Load = readings[8]
|
|
238
|
+
self.R_Input_Voltage = readings[9]
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
MB_Params.LD_TEMP: self.R_Diode_Temp,
|
|
242
|
+
MB_Params.CRYSTAL_TEMP: self.R_Crystal_Temp,
|
|
243
|
+
MB_Params.BODY_TEMP: self.R_Body_Temp,
|
|
244
|
+
MB_Params.LD_CURRENT: self.R_LD_Current,
|
|
245
|
+
MB_Params.CRYSTAL_TEC_LOAD: self.R_Crystal_TEC_Load,
|
|
246
|
+
MB_Params.LD_TEC_LOAD: self.R_LD_TEC_Load,
|
|
247
|
+
MB_Params.STATUS: self.R_Status,
|
|
248
|
+
MB_Params.FAN_LOAD: self.R_Fan_Load,
|
|
249
|
+
MB_Params.IN_VOLTAGE: self.R_Input_Voltage,
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return {}
|
|
253
|
+
|
|
254
|
+
def GetSettings(self, log_print: bool = True):
|
|
255
|
+
if self.isOpen():
|
|
256
|
+
res = self.SendCommand(io_combiner.SETTINGS, log_print)
|
|
257
|
+
|
|
258
|
+
if not ('<ERR>' in res or '<ACK>' in res):
|
|
259
|
+
readings = res.split(' ')
|
|
260
|
+
if len(readings) >= 10:
|
|
261
|
+
self.S_Crystal_Temp = float(readings[1]) / 100
|
|
262
|
+
self.S_Diode_Temp = float(readings[2]) / 100
|
|
263
|
+
self.S_LD_Current = float(readings[3])
|
|
264
|
+
self.S_Feedback_DAC = float(readings[4])
|
|
265
|
+
self.S_Power = float(readings[5])
|
|
266
|
+
self.S_LD_MaxCurrent = float(readings[6])
|
|
267
|
+
self.S_Autostart_Mode = readings[7]
|
|
268
|
+
self.S_Access_Level = int(readings[8])
|
|
269
|
+
self.S_Fan_Temp = float(readings[9]) / 100
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
MB_Params.CRYSTAL_TEMP_SET: self.S_Crystal_Temp,
|
|
273
|
+
MB_Params.LD_TEMP_SET: self.S_Diode_Temp,
|
|
274
|
+
MB_Params.LD_CURRENT_SET: self.S_LD_Current,
|
|
275
|
+
MB_Params.FEEDBACK_DAC: self.S_Feedback_DAC,
|
|
276
|
+
MB_Params.POWER_READ: self.S_Power,
|
|
277
|
+
MB_Params.LD_CURRENT_MAX: self.S_LD_MaxCurrent,
|
|
278
|
+
MB_Params.AUTO_MODE: self.S_Autostart_Mode,
|
|
279
|
+
MB_Params.ACCESS_LEVEL: self.S_Access_Level,
|
|
280
|
+
MB_Params.FAN_TEMP_SET: self.S_Fan_Temp,
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return {}
|
|
284
|
+
|
|
285
|
+
def SetCurrent(self, index: int, value: int) -> bool:
|
|
286
|
+
if self.isOpen():
|
|
287
|
+
if not isinstance(value, int):
|
|
288
|
+
raise TypeError('Current must be an int!')
|
|
289
|
+
if value < 0 or value > self.Max[index - 1]:
|
|
290
|
+
raise ValueError(f'Current must be between 0 and {self.Max[index-1]}')
|
|
291
|
+
|
|
292
|
+
res = self.SendCommand(f'Lc{index:.0f} {value:.0f}'.encode())
|
|
293
|
+
|
|
294
|
+
return '<ACK>' in res
|
|
295
|
+
|
|
296
|
+
def SetDisabled(self, index: int) -> bool:
|
|
297
|
+
if self.isOpen():
|
|
298
|
+
res = self.SendCommand(f'L{index:.0f}D'.encode())
|
|
299
|
+
|
|
300
|
+
return '<ACK>' in res
|
|
301
|
+
|
|
302
|
+
def SetEnabled(self, index: int) -> bool:
|
|
303
|
+
if self.isOpen():
|
|
304
|
+
res = self.SendCommand(f'L{index:.0f}E'.encode())
|
|
305
|
+
|
|
306
|
+
return '<ACK>' in res
|
|
307
|
+
|
|
308
|
+
def GetInfo(self):
|
|
309
|
+
if self.isOpen():
|
|
310
|
+
res = self.SendCommand(io_combiner.INFO, delay=50)
|
|
311
|
+
|
|
312
|
+
if not ('<ERR>' in res or '<ACK>' in res):
|
|
313
|
+
info = res.split('\r\n')
|
|
314
|
+
|
|
315
|
+
self.Firmware = info[0]
|
|
316
|
+
self.Serial = info[1].split(':')[1]
|
|
317
|
+
self.Model = info[2].split(':')[1]
|
|
318
|
+
self.Operation_Time = info[3]
|
|
319
|
+
self.ON_Times = info[4]
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class LaserSwitches:
|
|
323
|
+
def __init__(self, Laser: io_combiner, index=1, wavelength=638) -> None:
|
|
324
|
+
super().__init__()
|
|
325
|
+
|
|
326
|
+
self.Laser = Laser
|
|
327
|
+
self.index = index
|
|
328
|
+
self.wavelength = wavelength
|
|
329
|
+
self.state = LaserState.OFF
|
|
330
|
+
self.max_current = Laser.Max[index - 1]
|
|
331
|
+
|
|
332
|
+
self.STATE = f'Options.{self.wavelength:d}nm State'
|
|
333
|
+
self.CURRENT = f'Options.{self.wavelength:d}nm Current [mA]'
|
|
334
|
+
|
|
335
|
+
def laser_state_changed(self, param: Parameter, value):
|
|
336
|
+
'''Sends enable/disable signals to the
|
|
337
|
+
laser combiner according to selected setting
|
|
338
|
+
|
|
339
|
+
Parameters
|
|
340
|
+
----------
|
|
341
|
+
object : [QRadioButton]
|
|
342
|
+
the radio button toggled
|
|
343
|
+
'''
|
|
344
|
+
self.state = value
|
|
345
|
+
if self.state == LaserState.OFF:
|
|
346
|
+
self.Laser.SetDisabled(self.index)
|
|
347
|
+
else:
|
|
348
|
+
self.Laser.SetEnabled(self.index)
|
|
349
|
+
|
|
350
|
+
def SetCurrent(self, value):
|
|
351
|
+
self.Laser.SetCurrent(self.index, value)
|
|
352
|
+
|
|
353
|
+
def GetRelayState(self):
|
|
354
|
+
return f'L{self.wavelength:d}{self.state}'
|
|
355
|
+
|
|
356
|
+
def add_params(self, parent: Tree):
|
|
357
|
+
params = [
|
|
358
|
+
{
|
|
359
|
+
'name': self.STATE.split('.')[1],
|
|
360
|
+
'type': 'list',
|
|
361
|
+
'value': LaserState.OFF,
|
|
362
|
+
'limits': LaserState.get_list(),
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
'name': self.CURRENT.split('.')[1],
|
|
366
|
+
'type': 'int',
|
|
367
|
+
'value': 0,
|
|
368
|
+
'limits': [0, self.max_current],
|
|
369
|
+
},
|
|
370
|
+
]
|
|
371
|
+
for param in params:
|
|
372
|
+
parent.add_param_child(MB_Params.OPTIONS, param)
|
|
373
|
+
|
|
374
|
+
parent.get_param(self.STATE).sigValueChanged.connect(self.laser_state_changed)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
class CombinerLaserWidget(Tree):
|
|
378
|
+
PARAMS = MB_Params
|
|
379
|
+
removed = Signal(object)
|
|
380
|
+
|
|
381
|
+
def __init__(self, parent: Optional['QtWidgets.QWidget'] = None):
|
|
382
|
+
'''Initializes a new CombinerLaserWidget instance.
|
|
383
|
+
|
|
384
|
+
Parameters
|
|
385
|
+
----------
|
|
386
|
+
parent : Optional[QWidget]
|
|
387
|
+
The parent widget for this CombinerLaserWidget instance.
|
|
388
|
+
|
|
389
|
+
Attributes
|
|
390
|
+
----------
|
|
391
|
+
Laser : io_combiner
|
|
392
|
+
The `io_combiner` instance used to communicate with the device.
|
|
393
|
+
'''
|
|
394
|
+
super().__init__()
|
|
395
|
+
|
|
396
|
+
self.Laser = io_combiner()
|
|
397
|
+
|
|
398
|
+
self._laserSwitches: list[LaserSwitches] = []
|
|
399
|
+
|
|
400
|
+
# Statues Bar Timer
|
|
401
|
+
self.timer = QtCore.QTimer()
|
|
402
|
+
self.timer.setInterval(500)
|
|
403
|
+
self.timer.timeout.connect(self.update_stats)
|
|
404
|
+
self.timer.start()
|
|
405
|
+
|
|
406
|
+
def create_parameters(self):
|
|
407
|
+
'''
|
|
408
|
+
Create the parameter tree structure.
|
|
409
|
+
'''
|
|
410
|
+
params = [
|
|
411
|
+
{
|
|
412
|
+
'name': str(MB_Params.MODEL),
|
|
413
|
+
'type': 'str',
|
|
414
|
+
'value': 'N/A',
|
|
415
|
+
'readonly': True,
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
'name': str(MB_Params.WAVELENGTHS),
|
|
419
|
+
'type': 'str',
|
|
420
|
+
'value': 'N/A',
|
|
421
|
+
'readonly': True,
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
'name': str(MB_Params.SERIAL_PORT),
|
|
425
|
+
'type': 'group',
|
|
426
|
+
'expanded' : False,
|
|
427
|
+
'children': [
|
|
428
|
+
{
|
|
429
|
+
'name': str(MB_Params.PORT),
|
|
430
|
+
'type': 'list',
|
|
431
|
+
'limits': [
|
|
432
|
+
info.portName()
|
|
433
|
+
for info in QtSerialPort.QSerialPortInfo.availablePorts()
|
|
434
|
+
],
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
'name': str(MB_Params.BAUDRATE),
|
|
438
|
+
'type': 'list',
|
|
439
|
+
'value': 115200,
|
|
440
|
+
'limits': [
|
|
441
|
+
baudrate
|
|
442
|
+
for baudrate in \
|
|
443
|
+
QtSerialPort.QSerialPortInfo.standardBaudRates()
|
|
444
|
+
],
|
|
445
|
+
},
|
|
446
|
+
{'name': str(MB_Params.SET_PORT), 'type': 'action'},
|
|
447
|
+
{'name': str(MB_Params.OPEN), 'type': 'action'},
|
|
448
|
+
{'name': str(MB_Params.CLOSE), 'type': 'action'},
|
|
449
|
+
{
|
|
450
|
+
'name': str(MB_Params.PORT_STATE),
|
|
451
|
+
'type': 'str',
|
|
452
|
+
'value': 'closed',
|
|
453
|
+
'readonly': True,
|
|
454
|
+
},
|
|
455
|
+
],
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
'name': str(MB_Params.OPTIONS),
|
|
459
|
+
'type': 'group',
|
|
460
|
+
'children': [
|
|
461
|
+
{'name': str(MB_Params.SET_CURRENT), 'type': 'action'},
|
|
462
|
+
],
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
'name': str(MB_Params.READINGS),
|
|
466
|
+
'type': 'group',
|
|
467
|
+
'children': [
|
|
468
|
+
{
|
|
469
|
+
'name': str(MB_Params.POWER_READ),
|
|
470
|
+
'type': 'str',
|
|
471
|
+
'value': '0',
|
|
472
|
+
'readonly': True,
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
'name': str(MB_Params.LD_CURRENT),
|
|
476
|
+
'type': 'str',
|
|
477
|
+
'value': '0',
|
|
478
|
+
'readonly': True,
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
'name': str(MB_Params.LD_CURRENT_SET),
|
|
482
|
+
'type': 'str',
|
|
483
|
+
'value': '0',
|
|
484
|
+
'readonly': True,
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
'name': str(MB_Params.LD_CURRENT_MAX),
|
|
488
|
+
'type': 'str',
|
|
489
|
+
'value': '0',
|
|
490
|
+
'readonly': True,
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
'name': str(MB_Params.LD_TEMP),
|
|
494
|
+
'type': 'str',
|
|
495
|
+
'value': '0',
|
|
496
|
+
'readonly': True,
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
'name': str(MB_Params.LD_TEMP_SET),
|
|
500
|
+
'type': 'str',
|
|
501
|
+
'value': '0',
|
|
502
|
+
'readonly': True,
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
'name': str(MB_Params.LD_TEC_LOAD),
|
|
506
|
+
'type': 'str',
|
|
507
|
+
'value': '0',
|
|
508
|
+
'readonly': True,
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
'name': str(MB_Params.CRYSTAL_TEMP),
|
|
512
|
+
'type': 'str',
|
|
513
|
+
'value': '0',
|
|
514
|
+
'readonly': True,
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
'name': str(MB_Params.CRYSTAL_TEMP_SET),
|
|
518
|
+
'type': 'str',
|
|
519
|
+
'value': '0',
|
|
520
|
+
'readonly': True,
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
'name': str(MB_Params.CRYSTAL_TEC_LOAD),
|
|
524
|
+
'type': 'str',
|
|
525
|
+
'value': '0',
|
|
526
|
+
'readonly': True,
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
'name': str(MB_Params.BODY_TEMP),
|
|
530
|
+
'type': 'str',
|
|
531
|
+
'value': '0',
|
|
532
|
+
'readonly': True,
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
'name': str(MB_Params.FAN_TEMP_SET),
|
|
536
|
+
'type': 'str',
|
|
537
|
+
'value': '0',
|
|
538
|
+
'readonly': True,
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
'name': str(MB_Params.FAN_LOAD),
|
|
542
|
+
'type': 'str',
|
|
543
|
+
'value': '0',
|
|
544
|
+
'readonly': True,
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
'name': str(MB_Params.FEEDBACK_DAC),
|
|
548
|
+
'type': 'str',
|
|
549
|
+
'value': '0',
|
|
550
|
+
'readonly': True,
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
'name': str(MB_Params.AUTO_MODE),
|
|
554
|
+
'type': 'str',
|
|
555
|
+
'value': '0',
|
|
556
|
+
'readonly': True,
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
'name': str(MB_Params.ACCESS_LEVEL),
|
|
560
|
+
'type': 'str',
|
|
561
|
+
'value': '0',
|
|
562
|
+
'readonly': True,
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
'name': str(MB_Params.STATUS),
|
|
566
|
+
'type': 'str',
|
|
567
|
+
'value': '0',
|
|
568
|
+
'readonly': True,
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
'name': str(MB_Params.IN_VOLTAGE),
|
|
572
|
+
'type': 'str',
|
|
573
|
+
'value': '0',
|
|
574
|
+
'readonly': True,
|
|
575
|
+
},
|
|
576
|
+
],
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
'name': str(MB_Params.INFO),
|
|
580
|
+
'type': 'group',
|
|
581
|
+
'children': [
|
|
582
|
+
{
|
|
583
|
+
'name': str(MB_Params.FIRMWARE),
|
|
584
|
+
'type': 'str',
|
|
585
|
+
'value': 'N/A',
|
|
586
|
+
'readonly': True,
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
'name': str(MB_Params.SERIAL),
|
|
590
|
+
'type': 'str',
|
|
591
|
+
'value': 'N/A',
|
|
592
|
+
'readonly': True,
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
'name': str(MB_Params.OPERATION_TIME),
|
|
596
|
+
'type': 'str',
|
|
597
|
+
'value': 'N/A',
|
|
598
|
+
'readonly': True,
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
'name': str(MB_Params.ON_TIMES),
|
|
602
|
+
'type': 'str',
|
|
603
|
+
'value': 'N/A',
|
|
604
|
+
'readonly': True,
|
|
605
|
+
},
|
|
606
|
+
],
|
|
607
|
+
},
|
|
608
|
+
{'name': str(MB_Params.REMOVE), 'type': 'action'},
|
|
609
|
+
]
|
|
610
|
+
|
|
611
|
+
self.param_tree = Parameter.create(name='', type='group', children=params)
|
|
612
|
+
self.param_tree.sigTreeStateChanged.connect(self.change)
|
|
613
|
+
self.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents)
|
|
614
|
+
|
|
615
|
+
self.get_param(MB_Params.SET_PORT).sigActivated.connect(self.set_config)
|
|
616
|
+
self.get_param(MB_Params.OPEN).sigActivated.connect(self.laser_connect)
|
|
617
|
+
self.get_param(MB_Params.CLOSE).sigActivated.connect(
|
|
618
|
+
lambda: self.Laser.CloseCOM()
|
|
619
|
+
)
|
|
620
|
+
self.get_param(MB_Params.SET_CURRENT).sigActivated.connect(self.set_current)
|
|
621
|
+
|
|
622
|
+
self.get_param(MB_Params.REMOVE).sigActivated.connect(self.remove_widget)
|
|
623
|
+
|
|
624
|
+
def laser_connect(self):
|
|
625
|
+
'''Connects to the MatchBox device.
|
|
626
|
+
|
|
627
|
+
This method opens the serial port and initializes the laser.
|
|
628
|
+
'''
|
|
629
|
+
self.Laser.OpenCOM()
|
|
630
|
+
|
|
631
|
+
self.set_param_value(MB_Params.MODEL, self.Laser.Model)
|
|
632
|
+
self.set_param_value(MB_Params.WAVELENGTHS, str(self.Laser.Wavelengths))
|
|
633
|
+
self.set_param_value(MB_Params.FIRMWARE, self.Laser.Firmware)
|
|
634
|
+
self.set_param_value(MB_Params.SERIAL, self.Laser.Serial)
|
|
635
|
+
|
|
636
|
+
if not self._laserSwitches:
|
|
637
|
+
for idx in range(len(self.Laser.Wavelengths)):
|
|
638
|
+
if self.Laser.Wavelengths[idx] > 0:
|
|
639
|
+
switch = LaserSwitches(
|
|
640
|
+
self.Laser, idx + 1, self.Laser.Wavelengths[idx]
|
|
641
|
+
)
|
|
642
|
+
switch.add_params(self)
|
|
643
|
+
self._laserSwitches.append(switch)
|
|
644
|
+
|
|
645
|
+
def set_config(self):
|
|
646
|
+
'''Sets the serial port configuration.
|
|
647
|
+
|
|
648
|
+
This method sets the serial port configuration based on the current
|
|
649
|
+
settings in the parameter tree.
|
|
650
|
+
'''
|
|
651
|
+
if not self.Laser.isOpen():
|
|
652
|
+
self.Laser.setPortName(self.get_param_value(MB_Params.PORT))
|
|
653
|
+
self.Laser.setBaudRate(self.get_param_value(MB_Params.BAUDRATE))
|
|
654
|
+
|
|
655
|
+
def set_current(self):
|
|
656
|
+
for switch in self._laserSwitches:
|
|
657
|
+
value = self.get_param(switch.CURRENT).value()
|
|
658
|
+
switch.SetCurrent(value)
|
|
659
|
+
|
|
660
|
+
def update_stats(self):
|
|
661
|
+
"""
|
|
662
|
+
Updates the statistics displayed in the MatchBox GUI.
|
|
663
|
+
|
|
664
|
+
This method retrieves the current readings and settings from the device, and
|
|
665
|
+
updates the corresponding parameter tree items with the new values. It also
|
|
666
|
+
sets the limits of the power parameter based on the maximum power that can be
|
|
667
|
+
set for the laser diode.
|
|
668
|
+
|
|
669
|
+
If the laser is not connected, the method sets the 'Port State' parameter to
|
|
670
|
+
'closed'.
|
|
671
|
+
"""
|
|
672
|
+
if self.Laser.isOpen():
|
|
673
|
+
readings = self.Laser.GetReadings(False)
|
|
674
|
+
settings = self.Laser.GetSettings(False)
|
|
675
|
+
self.Laser.GetCurrent()
|
|
676
|
+
|
|
677
|
+
for key, value in readings.items():
|
|
678
|
+
if isinstance(value, (int, float)):
|
|
679
|
+
self.set_param_value(key, f'{value:.2f}')
|
|
680
|
+
elif isinstance(value, str):
|
|
681
|
+
self.set_param_value(key, value)
|
|
682
|
+
|
|
683
|
+
for key, value in settings.items():
|
|
684
|
+
if isinstance(value, (int, float)):
|
|
685
|
+
self.set_param_value(key, f'{value:.2f}')
|
|
686
|
+
elif isinstance(value, str):
|
|
687
|
+
self.set_param_value(key, value)
|
|
688
|
+
|
|
689
|
+
self.set_param_value(
|
|
690
|
+
MB_Params.LD_CURRENT,
|
|
691
|
+
'{:.2f} mA, {:.2f} mA, {:.2f} mA, {:.2f} mA'.format(
|
|
692
|
+
*self.Laser.Current
|
|
693
|
+
),
|
|
694
|
+
)
|
|
695
|
+
self.set_param_value(
|
|
696
|
+
MB_Params.LD_CURRENT_MAX,
|
|
697
|
+
'{:.2f} mA, {:.2f} mA, {:.2f} mA, {:.2f} mA'.format(*self.Laser.Max),
|
|
698
|
+
)
|
|
699
|
+
self.set_param_value(
|
|
700
|
+
MB_Params.LD_CURRENT_SET,
|
|
701
|
+
'{:.2f} mA, {:.2f} mA, {:.2f} mA, {:.2f} mA'.format(
|
|
702
|
+
*self.Laser.Setting
|
|
703
|
+
),
|
|
704
|
+
)
|
|
705
|
+
|
|
706
|
+
self.set_param_value(MB_Params.OPERATION_TIME, self.Laser.Operation_Time)
|
|
707
|
+
self.set_param_value(MB_Params.ON_TIMES, self.Laser.ON_Times)
|
|
708
|
+
|
|
709
|
+
self.set_param_value(MB_Params.PORT_STATE, 'open')
|
|
710
|
+
else:
|
|
711
|
+
self.set_param_value(MB_Params.PORT_STATE, 'closed')
|
|
712
|
+
|
|
713
|
+
self.RefreshPorts()
|
|
714
|
+
|
|
715
|
+
def RefreshPorts(self):
|
|
716
|
+
"""
|
|
717
|
+
Refreshes the available serial ports list in the GUI.
|
|
718
|
+
|
|
719
|
+
This method updates the list of available serial ports in the GUI by fetching
|
|
720
|
+
the current list of available ports and setting it as the options for the
|
|
721
|
+
'Serial Port' parameter in the parameter tree.
|
|
722
|
+
"""
|
|
723
|
+
if not self.Laser.isOpen():
|
|
724
|
+
self.get_param(MB_Params.PORT).setLimits(
|
|
725
|
+
[
|
|
726
|
+
info.portName()
|
|
727
|
+
for info in QtSerialPort.QSerialPortInfo.availablePorts()
|
|
728
|
+
]
|
|
729
|
+
)
|
|
730
|
+
|
|
731
|
+
def GetRelayState(self):
|
|
732
|
+
states = ''
|
|
733
|
+
for switch in self._laserSwitches:
|
|
734
|
+
states += switch.GetRelayState()
|
|
735
|
+
return states
|
|
736
|
+
|
|
737
|
+
def get_config(self) -> dict:
|
|
738
|
+
'''
|
|
739
|
+
Returns the current configuration of the laser device as a dictionary.
|
|
740
|
+
'''
|
|
741
|
+
return {
|
|
742
|
+
'port': self.Laser.portName(),
|
|
743
|
+
'baudrate': self.Laser.baudRate(),
|
|
744
|
+
'class': self.__class__.__name__,
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
def load_config(self, config: dict) -> bool:
|
|
748
|
+
'''
|
|
749
|
+
Loads the configuration from the given dictionary.
|
|
750
|
+
'''
|
|
751
|
+
port = config.get('port')
|
|
752
|
+
baudrate = config.get('baudrate')
|
|
753
|
+
if port:
|
|
754
|
+
self.Laser.setPortName(port)
|
|
755
|
+
self.set_param_value(MB_Params.PORT, port)
|
|
756
|
+
if baudrate:
|
|
757
|
+
self.Laser.setBaudRate(baudrate)
|
|
758
|
+
self.set_param_value(MB_Params.BAUDRATE, baudrate)
|
|
759
|
+
|
|
760
|
+
def remove_widget(self):
|
|
761
|
+
if self.parent() and not self.Laser.isOpen():
|
|
762
|
+
self.parent().removeWidget(self)
|
|
763
|
+
self.removed.emit(self)
|
|
764
|
+
self.deleteLater()
|
|
765
|
+
else:
|
|
766
|
+
print(f'Disconnect device {self.Laser.Model} before removing!')
|
|
767
|
+
|
|
768
|
+
def __str__(self):
|
|
769
|
+
return self.Laser.Model.strip() or self.__class__.__name__
|
|
770
|
+
|
|
771
|
+
def StartGUI():
|
|
772
|
+
'''Initializes a new QApplication and CombinerLaserWidget.
|
|
773
|
+
|
|
774
|
+
Use
|
|
775
|
+
-------
|
|
776
|
+
app, window = CombinerLaserWidget.StartGUI()
|
|
777
|
+
|
|
778
|
+
app.exec()
|
|
779
|
+
|
|
780
|
+
Returns
|
|
781
|
+
-------
|
|
782
|
+
tuple (QApplication, CombinerLaserWidget)
|
|
783
|
+
Returns a tuple with QApp and CombinerLaserWidget main window.
|
|
784
|
+
'''
|
|
785
|
+
return StartGUI(CombinerLaserWidget)
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
if __name__ == '__main__':
|
|
789
|
+
app, widget = CombinerLaserWidget.StartGUI()
|
|
790
|
+
|
|
791
|
+
app.exec()
|