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,89 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
from microEye.qt import QtWidgets
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class stage:
|
|
7
|
+
def __init__(self) -> None:
|
|
8
|
+
'''
|
|
9
|
+
Initialize the stage object.
|
|
10
|
+
|
|
11
|
+
This method initializes the `stage` object with the starter values.
|
|
12
|
+
'''
|
|
13
|
+
self._connect_btn = QtWidgets.QPushButton()
|
|
14
|
+
self.ZPosition = 50000
|
|
15
|
+
self.LastCmd = ''
|
|
16
|
+
self.Received = ''
|
|
17
|
+
|
|
18
|
+
def isOpen(self):
|
|
19
|
+
'''
|
|
20
|
+
Check if the stage is open.
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
is_open : bool
|
|
25
|
+
A boolean value indicating whether the stage is open.
|
|
26
|
+
'''
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class XYStageParams(Enum):
|
|
31
|
+
'''
|
|
32
|
+
Enum class defining XY Stage parameters.
|
|
33
|
+
'''
|
|
34
|
+
|
|
35
|
+
MODEL = 'Model'
|
|
36
|
+
STATUS = 'Status'
|
|
37
|
+
|
|
38
|
+
X_POSITION = 'X Position'
|
|
39
|
+
Y_POSITION = 'Y Position'
|
|
40
|
+
GET_POSITION = 'Get Position'
|
|
41
|
+
|
|
42
|
+
MOVE = 'Move'
|
|
43
|
+
HOME = 'Home'
|
|
44
|
+
CENTER = 'Center'
|
|
45
|
+
STOP = 'Stop !'
|
|
46
|
+
|
|
47
|
+
CONTROLS = 'Controls'
|
|
48
|
+
X_JUMP_P = 'Controls.X++'
|
|
49
|
+
X_JUMP_N = 'Controls.X--'
|
|
50
|
+
X_STEP_P = 'Controls.X+'
|
|
51
|
+
X_STEP_N = 'Controls.X-'
|
|
52
|
+
|
|
53
|
+
Y_JUMP_P = 'Controls.Y++'
|
|
54
|
+
Y_JUMP_N = 'Controls.Y--'
|
|
55
|
+
Y_STEP_P = 'Controls.Y+'
|
|
56
|
+
Y_STEP_N = 'Controls.Y-'
|
|
57
|
+
|
|
58
|
+
OPTIONS = 'Options'
|
|
59
|
+
STEP = 'Options.Step Size'
|
|
60
|
+
JUMP = 'Options.Jump Size'
|
|
61
|
+
ID_X = 'Options.ID X'
|
|
62
|
+
ID_Y = 'Options.ID Y'
|
|
63
|
+
|
|
64
|
+
SERIAL_PORT = 'Serial Port'
|
|
65
|
+
PORT = 'Serial Port.Port'
|
|
66
|
+
BAUDRATE = 'Serial Port.Baudrate'
|
|
67
|
+
REFRESH = 'Serial Port.Refresh Ports'
|
|
68
|
+
SET_PORT = 'Serial Port.Set Config'
|
|
69
|
+
SET_PORT_X = 'Serial Port.Set Config X'
|
|
70
|
+
SET_PORT_Y = 'Serial Port.Set Config Y'
|
|
71
|
+
OPEN = 'Serial Port.Connect'
|
|
72
|
+
CLOSE = 'Serial Port.Disconnect'
|
|
73
|
+
PORT_STATE = 'Serial Port.State'
|
|
74
|
+
|
|
75
|
+
INFO = 'Info'
|
|
76
|
+
|
|
77
|
+
REMOVE = 'Remove Device'
|
|
78
|
+
|
|
79
|
+
def __str__(self):
|
|
80
|
+
'''
|
|
81
|
+
Return the last part of the enum value (Param name).
|
|
82
|
+
'''
|
|
83
|
+
return self.value.split('.')[-1]
|
|
84
|
+
|
|
85
|
+
def get_path(self):
|
|
86
|
+
'''
|
|
87
|
+
Return the full parameter path.
|
|
88
|
+
'''
|
|
89
|
+
return self.value.split('.')
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from microEye.hardware.widgets.controller import Controller
|
|
2
|
+
from microEye.hardware.widgets.devices import DevicesView, devicesParams
|
|
3
|
+
from microEye.hardware.widgets.focusWidget import focusWidget
|
|
4
|
+
from microEye.hardware.widgets.qlist_slider import QListSlider
|
|
5
|
+
from microEye.hardware.widgets.scan_acquisition import (
|
|
6
|
+
ScanAcquisitionWidget,
|
|
7
|
+
ScanParams,
|
|
8
|
+
TiledImageSelector,
|
|
9
|
+
TileImage,
|
|
10
|
+
)
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pyqtgraph as pg
|
|
5
|
+
|
|
6
|
+
from microEye.hardware.stages.stabilizer import *
|
|
7
|
+
from microEye.qt import QtWidgets
|
|
8
|
+
from microEye.utils.gui_helper import GaussianOffSet
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Controller(QtWidgets.QDockWidget):
|
|
12
|
+
stage_move_requested = Signal(str, int, float)
|
|
13
|
+
stage_stop_requested = Signal(str)
|
|
14
|
+
stage_home_requested = Signal(str)
|
|
15
|
+
stage_toggle_lock = Signal(str)
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
''' '''
|
|
19
|
+
super().__init__('Controller Unit')
|
|
20
|
+
|
|
21
|
+
# Remove close button from dock widgets
|
|
22
|
+
self.setFeatures(
|
|
23
|
+
QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable
|
|
24
|
+
| QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
self.init_layout()
|
|
28
|
+
|
|
29
|
+
self.connect_signals()
|
|
30
|
+
|
|
31
|
+
def init_layout(self):
|
|
32
|
+
# display tab
|
|
33
|
+
self.labelStyle = {'color': '#FFF', 'font-size': '10pt'}
|
|
34
|
+
|
|
35
|
+
main_layout = QtWidgets.QVBoxLayout()
|
|
36
|
+
main_widget = QtWidgets.QWidget()
|
|
37
|
+
main_widget.setLayout(main_layout)
|
|
38
|
+
self.setWidget(main_widget)
|
|
39
|
+
|
|
40
|
+
# Movement settings group
|
|
41
|
+
settings_group = QtWidgets.QGroupBox('Movement Settings')
|
|
42
|
+
settings_layout = QtWidgets.QGridLayout()
|
|
43
|
+
|
|
44
|
+
# XY Step size controls
|
|
45
|
+
self.xy_coarse_step = QtWidgets.QDoubleSpinBox()
|
|
46
|
+
self.xy_coarse_step.setRange(0, 5000.0) # 1µm to 5mm
|
|
47
|
+
self.xy_coarse_step.setValue(500.0)
|
|
48
|
+
self.xy_coarse_step.setSingleStep(100.0)
|
|
49
|
+
self.xy_coarse_step.setSuffix(' µm')
|
|
50
|
+
|
|
51
|
+
self.xy_fine_step = QtWidgets.QDoubleSpinBox()
|
|
52
|
+
self.xy_fine_step.setRange(0.0, 100.0) # 100nm to 10µm
|
|
53
|
+
self.xy_fine_step.setValue(50.0)
|
|
54
|
+
self.xy_fine_step.setSingleStep(5.0)
|
|
55
|
+
self.xy_fine_step.setSuffix(' µm')
|
|
56
|
+
self.xy_fine_step.setDecimals(3)
|
|
57
|
+
|
|
58
|
+
# Z Step size controls
|
|
59
|
+
self.z_coarse_step = QtWidgets.QDoubleSpinBox()
|
|
60
|
+
self.z_coarse_step.setRange(0.0, 10.0) # 100nm to 10µm
|
|
61
|
+
self.z_coarse_step.setValue(1.0)
|
|
62
|
+
self.z_coarse_step.setSingleStep(0.5)
|
|
63
|
+
self.z_coarse_step.setSuffix(' µm')
|
|
64
|
+
|
|
65
|
+
self.z_fine_step = QtWidgets.QSpinBox()
|
|
66
|
+
self.z_fine_step.setRange(0, 1000) # 1nm to 1µm
|
|
67
|
+
self.z_fine_step.setValue(100)
|
|
68
|
+
self.z_fine_step.setSingleStep(10)
|
|
69
|
+
self.z_fine_step.setSuffix(' nm')
|
|
70
|
+
|
|
71
|
+
# Layout for step controls
|
|
72
|
+
settings_layout.addWidget(QtWidgets.QLabel('XY Fine:'), 0, 0)
|
|
73
|
+
settings_layout.addWidget(self.xy_fine_step, 0, 1)
|
|
74
|
+
settings_layout.addWidget(QtWidgets.QLabel('XY Coarse:'), 1, 0)
|
|
75
|
+
settings_layout.addWidget(self.xy_coarse_step, 1, 1)
|
|
76
|
+
settings_layout.addWidget(QtWidgets.QLabel('Z Fine:'), 2, 0)
|
|
77
|
+
settings_layout.addWidget(self.z_fine_step, 2, 1)
|
|
78
|
+
settings_layout.addWidget(QtWidgets.QLabel('Z Coarse:'), 3, 0)
|
|
79
|
+
settings_layout.addWidget(self.z_coarse_step, 3, 1)
|
|
80
|
+
|
|
81
|
+
settings_group.setLayout(settings_layout)
|
|
82
|
+
|
|
83
|
+
# XY Controls group
|
|
84
|
+
xy_group = QtWidgets.QGroupBox('XY Control')
|
|
85
|
+
xy_layout = QtWidgets.QGridLayout()
|
|
86
|
+
|
|
87
|
+
# XY Buttons
|
|
88
|
+
self.btn_y_up = QtWidgets.QPushButton('++')
|
|
89
|
+
self.btn_y_down = QtWidgets.QPushButton('--')
|
|
90
|
+
self.btn_x_left = QtWidgets.QPushButton('--')
|
|
91
|
+
self.btn_x_right = QtWidgets.QPushButton('++')
|
|
92
|
+
|
|
93
|
+
# Fine movement buttons
|
|
94
|
+
self.btn_y_up_fine = QtWidgets.QPushButton('+')
|
|
95
|
+
self.btn_y_down_fine = QtWidgets.QPushButton('-')
|
|
96
|
+
self.btn_x_left_fine = QtWidgets.QPushButton('-')
|
|
97
|
+
self.btn_x_right_fine = QtWidgets.QPushButton('+')
|
|
98
|
+
|
|
99
|
+
self.btn_xy_stop = QtWidgets.QPushButton('⚠')
|
|
100
|
+
self.btn_xy_stop.setToolTip('Stop XY movement immediately!')
|
|
101
|
+
|
|
102
|
+
# Set size policies and styling
|
|
103
|
+
for btn in [
|
|
104
|
+
self.btn_y_up,
|
|
105
|
+
self.btn_y_down,
|
|
106
|
+
self.btn_x_left,
|
|
107
|
+
self.btn_x_right,
|
|
108
|
+
self.btn_y_up_fine,
|
|
109
|
+
self.btn_y_down_fine,
|
|
110
|
+
self.btn_x_left_fine,
|
|
111
|
+
self.btn_x_right_fine,
|
|
112
|
+
self.btn_xy_stop,
|
|
113
|
+
]:
|
|
114
|
+
btn.setFixedSize(50, 50)
|
|
115
|
+
btn.setStyleSheet('''
|
|
116
|
+
QPushButton {
|
|
117
|
+
font-weight: bold;
|
|
118
|
+
font-size: 22px;
|
|
119
|
+
padding: 0px;
|
|
120
|
+
}
|
|
121
|
+
''')
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# Layout XY controls
|
|
125
|
+
xy_layout.addWidget(self.btn_y_up_fine, 1, 2)
|
|
126
|
+
xy_layout.addWidget(self.btn_y_up, 0, 2)
|
|
127
|
+
xy_layout.addWidget(self.btn_y_down, 4, 2)
|
|
128
|
+
xy_layout.addWidget(self.btn_y_down_fine, 3, 2)
|
|
129
|
+
|
|
130
|
+
xy_layout.addWidget(self.btn_x_left_fine, 2, 1)
|
|
131
|
+
xy_layout.addWidget(self.btn_x_left, 2, 0)
|
|
132
|
+
xy_layout.addWidget(self.btn_x_right, 2, 4)
|
|
133
|
+
xy_layout.addWidget(self.btn_x_right_fine, 2, 3)
|
|
134
|
+
|
|
135
|
+
xy_layout.addWidget(self.btn_xy_stop, 2, 2)
|
|
136
|
+
|
|
137
|
+
xy_group.setLayout(xy_layout)
|
|
138
|
+
|
|
139
|
+
# Z Controls group
|
|
140
|
+
z_group = QtWidgets.QGroupBox('Z Control')
|
|
141
|
+
z_layout = QtWidgets.QVBoxLayout()
|
|
142
|
+
|
|
143
|
+
self.btn_z_up = QtWidgets.QPushButton('++')
|
|
144
|
+
self.btn_z_down = QtWidgets.QPushButton('--')
|
|
145
|
+
self.btn_z_up_fine = QtWidgets.QPushButton('+')
|
|
146
|
+
self.btn_z_down_fine = QtWidgets.QPushButton('-')
|
|
147
|
+
self.btn_z_home = QtWidgets.QPushButton('🏠︎')
|
|
148
|
+
self.btn_z_home.setToolTip('Move to home position')
|
|
149
|
+
self.btn_z_toggle_stabilizer = QtWidgets.QPushButton('🔒')
|
|
150
|
+
self.btn_z_toggle_stabilizer.setToolTip('Toggle Z-axis stabilizer')
|
|
151
|
+
|
|
152
|
+
for btn in [
|
|
153
|
+
self.btn_z_up,
|
|
154
|
+
self.btn_z_down,
|
|
155
|
+
self.btn_z_up_fine,
|
|
156
|
+
self.btn_z_down_fine,
|
|
157
|
+
self.btn_z_home,
|
|
158
|
+
self.btn_z_toggle_stabilizer,
|
|
159
|
+
]:
|
|
160
|
+
btn.setFixedSize(50, 50)
|
|
161
|
+
btn.setStyleSheet('''
|
|
162
|
+
QPushButton {
|
|
163
|
+
font-weight: bold;
|
|
164
|
+
font-size: 22px;
|
|
165
|
+
padding: 0px;
|
|
166
|
+
}
|
|
167
|
+
''')
|
|
168
|
+
|
|
169
|
+
z_layout.addWidget(self.btn_z_up)
|
|
170
|
+
z_layout.addWidget(self.btn_z_up_fine)
|
|
171
|
+
z_layout.addWidget(self.btn_z_down_fine)
|
|
172
|
+
z_layout.addWidget(self.btn_z_down)
|
|
173
|
+
z_layout.addWidget(self.btn_z_home)
|
|
174
|
+
z_layout.addWidget(self.btn_z_toggle_stabilizer)
|
|
175
|
+
z_group.setLayout(z_layout)
|
|
176
|
+
|
|
177
|
+
# Create a container widget for XY and Z controls
|
|
178
|
+
controls_layout = QtWidgets.QHBoxLayout()
|
|
179
|
+
|
|
180
|
+
# Add XY and Z groups to horizontal layout
|
|
181
|
+
controls_layout.addWidget(xy_group)
|
|
182
|
+
controls_layout.addWidget(z_group)
|
|
183
|
+
|
|
184
|
+
# Add all groups to main layout
|
|
185
|
+
main_layout.addWidget(settings_group)
|
|
186
|
+
main_layout.addLayout(controls_layout)
|
|
187
|
+
main_layout.addStretch()
|
|
188
|
+
|
|
189
|
+
def connect_signals(self):
|
|
190
|
+
# XY coarse movements
|
|
191
|
+
self.btn_x_left.clicked.connect(lambda: self.move_stage('x', -1, 'coarse'))
|
|
192
|
+
self.btn_x_right.clicked.connect(lambda: self.move_stage('x', 1, 'coarse'))
|
|
193
|
+
self.btn_y_up.clicked.connect(lambda: self.move_stage('y', 1, 'coarse'))
|
|
194
|
+
self.btn_y_down.clicked.connect(lambda: self.move_stage('y', -1, 'coarse'))
|
|
195
|
+
|
|
196
|
+
# XY fine movements
|
|
197
|
+
self.btn_x_left_fine.clicked.connect(lambda: self.move_stage('x', -1, 'fine'))
|
|
198
|
+
self.btn_x_right_fine.clicked.connect(lambda: self.move_stage('x', 1, 'fine'))
|
|
199
|
+
self.btn_y_up_fine.clicked.connect(lambda: self.move_stage('y', 1, 'fine'))
|
|
200
|
+
self.btn_y_down_fine.clicked.connect(lambda: self.move_stage('y', -1, 'fine'))
|
|
201
|
+
|
|
202
|
+
self.btn_xy_stop.clicked.connect(
|
|
203
|
+
lambda: self.stage_stop_requested.emit('xy')
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
# Z movements
|
|
207
|
+
self.btn_z_up.clicked.connect(lambda: self.move_stage('z', 1, 'coarse'))
|
|
208
|
+
self.btn_z_down.clicked.connect(lambda: self.move_stage('z', -1, 'coarse'))
|
|
209
|
+
self.btn_z_up_fine.clicked.connect(lambda: self.move_stage('z', 1, 'fine'))
|
|
210
|
+
self.btn_z_down_fine.clicked.connect(lambda: self.move_stage('z', -1, 'fine'))
|
|
211
|
+
|
|
212
|
+
self.btn_z_home.clicked.connect(
|
|
213
|
+
lambda: self.stage_home_requested.emit('z')
|
|
214
|
+
)
|
|
215
|
+
self.btn_z_toggle_stabilizer.clicked.connect(
|
|
216
|
+
lambda: self.stage_toggle_lock.emit('z')
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
def move_stage(self, axis, direction, mode):
|
|
220
|
+
if axis in ['x', 'y']:
|
|
221
|
+
step = (
|
|
222
|
+
self.xy_coarse_step.value()
|
|
223
|
+
if mode == 'coarse'
|
|
224
|
+
else self.xy_fine_step.value()
|
|
225
|
+
)
|
|
226
|
+
step /= 1000 # Convert to mm
|
|
227
|
+
# print(f'Moving {axis} axis by {distance} µm')
|
|
228
|
+
else: # z-axis
|
|
229
|
+
if mode == 'coarse':
|
|
230
|
+
step = int(self.z_coarse_step.value() * 1000)
|
|
231
|
+
# print(f'Moving {axis} axis by {distance} µm')
|
|
232
|
+
else:
|
|
233
|
+
step = self.z_fine_step.value()
|
|
234
|
+
# print(f'Moving {axis} axis by {distance} nm')
|
|
235
|
+
|
|
236
|
+
self.stage_move_requested.emit(axis, direction, step)
|
|
237
|
+
|
|
238
|
+
def __str__(self):
|
|
239
|
+
return 'Controller Unit Widget'
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
if __name__ == '__main__':
|
|
243
|
+
app = QtWidgets.QApplication([])
|
|
244
|
+
controller = Controller()
|
|
245
|
+
controller.show()
|
|
246
|
+
app.exec()
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from pyqtgraph.parametertree import Parameter
|
|
5
|
+
|
|
6
|
+
from microEye.qt import QtWidgets, Signal
|
|
7
|
+
from microEye.utils import Tree
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class devicesParams(Enum):
|
|
11
|
+
'''
|
|
12
|
+
Enum class defining Devices parameters.
|
|
13
|
+
'''
|
|
14
|
+
|
|
15
|
+
IR_CAM = 'IR Detector'
|
|
16
|
+
IR_DEVICE = 'IR Detector.Device'
|
|
17
|
+
IR_SET = 'IR Detector.Set'
|
|
18
|
+
IR_RESET = 'IR Detector.Reset'
|
|
19
|
+
|
|
20
|
+
LASERS = 'Lasers'
|
|
21
|
+
LASER = 'Lasers.Laser'
|
|
22
|
+
ADD_LASER = 'Lasers.Add Laser'
|
|
23
|
+
|
|
24
|
+
STAGES = 'Stages'
|
|
25
|
+
STAGE = 'Stages.Stage'
|
|
26
|
+
SET_STAGE = 'Stages.Set Stage'
|
|
27
|
+
|
|
28
|
+
def __str__(self):
|
|
29
|
+
'''
|
|
30
|
+
Return the last part of the enum value (Param name).
|
|
31
|
+
'''
|
|
32
|
+
return self.value.split('.')[-1]
|
|
33
|
+
|
|
34
|
+
def get_path(self):
|
|
35
|
+
'''
|
|
36
|
+
Return the full parameter path.
|
|
37
|
+
'''
|
|
38
|
+
return self.value.split('.')
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class DevicesView(Tree):
|
|
42
|
+
'''Devices View used in miEye module to add lasers, stages, and IR detector.'''
|
|
43
|
+
|
|
44
|
+
PARAMS = devicesParams
|
|
45
|
+
setDetectorActivated = Signal(str)
|
|
46
|
+
resetDetectorActivated = Signal()
|
|
47
|
+
addLaserActivated = Signal(str)
|
|
48
|
+
setStageActivated = Signal(str)
|
|
49
|
+
|
|
50
|
+
def __init__(self, parent: Optional['QtWidgets.QWidget'] = None):
|
|
51
|
+
super().__init__(parent=parent)
|
|
52
|
+
|
|
53
|
+
def getDetectors(self):
|
|
54
|
+
return ['Demo Line Scanner', 'Parallax CCD (TSL1401)']
|
|
55
|
+
|
|
56
|
+
def getLasers(self):
|
|
57
|
+
return ['IO MatchBox Single Laser', 'IO MatchBox Laser Combiner']
|
|
58
|
+
|
|
59
|
+
def getStages(self):
|
|
60
|
+
return ['PiezoConcept FOC100']
|
|
61
|
+
|
|
62
|
+
def create_parameters(self):
|
|
63
|
+
'''
|
|
64
|
+
Create the parameter tree structure.
|
|
65
|
+
'''
|
|
66
|
+
params = [
|
|
67
|
+
{
|
|
68
|
+
'name': str(devicesParams.IR_CAM),
|
|
69
|
+
'type': 'group',
|
|
70
|
+
'children': [
|
|
71
|
+
{
|
|
72
|
+
'name': str(devicesParams.IR_DEVICE),
|
|
73
|
+
'title': '',
|
|
74
|
+
'type': 'list',
|
|
75
|
+
'limits': self.getDetectors(),
|
|
76
|
+
},
|
|
77
|
+
{'name': str(devicesParams.IR_SET), 'type': 'action'},
|
|
78
|
+
{'name': str(devicesParams.IR_RESET), 'type': 'action'},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
'name': str(devicesParams.LASERS),
|
|
83
|
+
'type': 'group',
|
|
84
|
+
'children': [
|
|
85
|
+
{
|
|
86
|
+
'name': str(devicesParams.LASER),
|
|
87
|
+
'title': '',
|
|
88
|
+
'type': 'list',
|
|
89
|
+
'limits': self.getLasers(),
|
|
90
|
+
},
|
|
91
|
+
{'name': str(devicesParams.ADD_LASER), 'type': 'action'},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
'name': str(devicesParams.STAGES),
|
|
96
|
+
'type': 'group',
|
|
97
|
+
'children': [
|
|
98
|
+
{
|
|
99
|
+
'name': str(devicesParams.STAGE),
|
|
100
|
+
'title': '',
|
|
101
|
+
'type': 'list',
|
|
102
|
+
'limits': self.getStages(),
|
|
103
|
+
},
|
|
104
|
+
{'name': str(devicesParams.SET_STAGE), 'type': 'action'},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
self.param_tree = Parameter.create(name='', type='group', children=params)
|
|
110
|
+
self.param_tree.sigTreeStateChanged.connect(self.change)
|
|
111
|
+
self.header().setSectionResizeMode(
|
|
112
|
+
QtWidgets.QHeaderView.ResizeMode.ResizeToContents
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
self.get_param(devicesParams.IR_SET).sigActivated.connect(
|
|
116
|
+
lambda: self.setDetectorActivated.emit(
|
|
117
|
+
self.get_param_value(devicesParams.IR_DEVICE)
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
self.get_param(devicesParams.IR_RESET).sigActivated.connect(
|
|
121
|
+
lambda: self.resetDetectorActivated.emit()
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
self.get_param(devicesParams.ADD_LASER).sigActivated.connect(
|
|
125
|
+
lambda: self.addLaserActivated.emit(
|
|
126
|
+
self.get_param_value(devicesParams.LASER)
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
self.get_param(devicesParams.SET_STAGE).sigActivated.connect(
|
|
130
|
+
lambda: self.setStageActivated.emit(
|
|
131
|
+
self.get_param_value(devicesParams.STAGE)
|
|
132
|
+
)
|
|
133
|
+
)
|