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.
Files changed (190) hide show
  1. microEye/__init__.py +47 -0
  2. microEye/_version.py +2 -0
  3. microEye/analysis/__init__.py +1 -0
  4. microEye/analysis/checklist_dialog.py +143 -0
  5. microEye/analysis/cmosMaps.py +228 -0
  6. microEye/analysis/filters/__init__.py +9 -0
  7. microEye/analysis/filters/base.py +21 -0
  8. microEye/analysis/filters/spatial.py +338 -0
  9. microEye/analysis/filters/temporal.py +76 -0
  10. microEye/analysis/fitting/__init__.py +0 -0
  11. microEye/analysis/fitting/fit.py +680 -0
  12. microEye/analysis/fitting/nena.py +375 -0
  13. microEye/analysis/fitting/phasor_fit.py +90 -0
  14. microEye/analysis/fitting/processing.py +317 -0
  15. microEye/analysis/fitting/psf/__init__.py +6 -0
  16. microEye/analysis/fitting/psf/extract.py +1129 -0
  17. microEye/analysis/fitting/psf/rubost_mean.py +150 -0
  18. microEye/analysis/fitting/psf/spline.py +167 -0
  19. microEye/analysis/fitting/psf/stats/__init__.py +12 -0
  20. microEye/analysis/fitting/psf/stats/core.py +295 -0
  21. microEye/analysis/fitting/psf/stats/curve_fit.py +708 -0
  22. microEye/analysis/fitting/psf/stats/io.py +104 -0
  23. microEye/analysis/fitting/psf/stats/slope_fit.py +171 -0
  24. microEye/analysis/fitting/psf/temp.py +147 -0
  25. microEye/analysis/fitting/psf/test.py +47 -0
  26. microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUfunctions.py +657 -0
  27. microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUmleFit_LM.py +1336 -0
  28. microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUsplineLib.py +270 -0
  29. microEye/analysis/fitting/pyfit3Dcspline/CPU/__init__.py +1 -0
  30. microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUfunctions.py +609 -0
  31. microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_EMCCD.py +1396 -0
  32. microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_sCMOS.py +1426 -0
  33. microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUsplineLib.py +231 -0
  34. microEye/analysis/fitting/pyfit3Dcspline/GPU/__init__.py +2 -0
  35. microEye/analysis/fitting/pyfit3Dcspline/__init__.py +10 -0
  36. microEye/analysis/fitting/pyfit3Dcspline/constants.py +27 -0
  37. microEye/analysis/fitting/pyfit3Dcspline/mainfunctions.py +903 -0
  38. microEye/analysis/fitting/results.py +917 -0
  39. microEye/analysis/fitting/results_stats.py +251 -0
  40. microEye/analysis/fitting/tardis.py +209 -0
  41. microEye/analysis/multi_viewer.py +568 -0
  42. microEye/analysis/processing/__init__.py +1 -0
  43. microEye/analysis/processing/frc.py +120 -0
  44. microEye/analysis/rendering/__init__.py +3 -0
  45. microEye/analysis/rendering/base.py +452 -0
  46. microEye/analysis/rendering/cloud.py +215 -0
  47. microEye/analysis/rendering/core.py +47 -0
  48. microEye/analysis/rendering/volumetric.py +198 -0
  49. microEye/analysis/tools/__init__.py +0 -0
  50. microEye/analysis/tools/kymograms.py +1079 -0
  51. microEye/analysis/tools/roi_selectors.py +556 -0
  52. microEye/analysis/utils/__init__.py +3 -0
  53. microEye/analysis/utils/coordinates.py +18 -0
  54. microEye/analysis/utils/images.py +68 -0
  55. microEye/analysis/utils/windows.py +19 -0
  56. microEye/analysis/viewer/__init__.py +3 -0
  57. microEye/analysis/viewer/image_options_widget.py +615 -0
  58. microEye/analysis/viewer/images.py +1225 -0
  59. microEye/analysis/viewer/layers_widget.py +415 -0
  60. microEye/analysis/viewer/localizations.py +1304 -0
  61. microEye/analysis/viewer/psf.py +1003 -0
  62. microEye/analysis/viewer/volume.py +456 -0
  63. microEye/hardware/__init__.py +3 -0
  64. microEye/hardware/cams/__init__.py +29 -0
  65. microEye/hardware/cams/camera_calibration.py +99 -0
  66. microEye/hardware/cams/camera_list.py +528 -0
  67. microEye/hardware/cams/camera_options.py +694 -0
  68. microEye/hardware/cams/camera_panel.py +941 -0
  69. microEye/hardware/cams/dummy/__init__.py +1 -0
  70. microEye/hardware/cams/dummy/dummy_panel.py +759 -0
  71. microEye/hardware/cams/jobs.py +497 -0
  72. microEye/hardware/cams/line_profiler.py +99 -0
  73. microEye/hardware/cams/linescan/IR_Cam.py +474 -0
  74. microEye/hardware/cams/linescan/__init__.py +1 -0
  75. microEye/hardware/cams/micam.py +524 -0
  76. microEye/hardware/cams/pco/__init__.py +58 -0
  77. microEye/hardware/cams/pco/enums.py +382 -0
  78. microEye/hardware/cams/pco/pco_cam.py +761 -0
  79. microEye/hardware/cams/pco/pco_panel.py +477 -0
  80. microEye/hardware/cams/shortcuts.py +312 -0
  81. microEye/hardware/cams/thorlabs/__init__.py +1 -0
  82. microEye/hardware/cams/thorlabs/thorlabs.py +1508 -0
  83. microEye/hardware/cams/thorlabs/thorlabs_panel.py +850 -0
  84. microEye/hardware/cams/ueye/__init__.py +1 -0
  85. microEye/hardware/cams/ueye/ueye_camera.py +1023 -0
  86. microEye/hardware/cams/ueye/ueye_panel.py +861 -0
  87. microEye/hardware/cams/vimba/__init__.py +1 -0
  88. microEye/hardware/cams/vimba/vimba_cam.py +1000 -0
  89. microEye/hardware/cams/vimba/vimba_panel.py +813 -0
  90. microEye/hardware/device.py +60 -0
  91. microEye/hardware/lasers/__init__.py +13 -0
  92. microEye/hardware/lasers/io_matchbox.py +791 -0
  93. microEye/hardware/lasers/io_params.py +85 -0
  94. microEye/hardware/lasers/io_single_laser.py +742 -0
  95. microEye/hardware/lasers/laser_relay.py +594 -0
  96. microEye/hardware/mieye/__init__.py +1 -0
  97. microEye/hardware/mieye/acquisition_manager.py +467 -0
  98. microEye/hardware/mieye/devices_manager.py +533 -0
  99. microEye/hardware/mieye/miEye.py +659 -0
  100. microEye/hardware/misc/__init__.py +0 -0
  101. microEye/hardware/misc/acquisition_view.py +71 -0
  102. microEye/hardware/misc/reglo.py +761 -0
  103. microEye/hardware/misc/temp.py +188 -0
  104. microEye/hardware/port_config.py +59 -0
  105. microEye/hardware/protocols/__init__.py +2 -0
  106. microEye/hardware/protocols/actions.py +402 -0
  107. microEye/hardware/protocols/actions_items.py +703 -0
  108. microEye/hardware/protocols/designer.py +244 -0
  109. microEye/hardware/protocols/scene_manager.py +191 -0
  110. microEye/hardware/protocols/serialization.py +97 -0
  111. microEye/hardware/pycromanager/__init__.py +16 -0
  112. microEye/hardware/pycromanager/core.py +1433 -0
  113. microEye/hardware/pycromanager/devices.py +461 -0
  114. microEye/hardware/pycromanager/enums.py +107 -0
  115. microEye/hardware/pycromanager/headless.py +153 -0
  116. microEye/hardware/pycromanager/utils.py +34 -0
  117. microEye/hardware/pycromanager/widgets/__init__.py +5 -0
  118. microEye/hardware/pycromanager/widgets/bridges.py +407 -0
  119. microEye/hardware/pycromanager/widgets/headless_manager.py +258 -0
  120. microEye/hardware/pycromanager/widgets/headless_options.py +224 -0
  121. microEye/hardware/pycromanager/widgets/pycro_panel.py +455 -0
  122. microEye/hardware/stages/__init__.py +18 -0
  123. microEye/hardware/stages/elliptec/__init__.py +5 -0
  124. microEye/hardware/stages/elliptec/baseDevice.py +314 -0
  125. microEye/hardware/stages/elliptec/device.py +384 -0
  126. microEye/hardware/stages/elliptec/deviceID.py +212 -0
  127. microEye/hardware/stages/elliptec/devicePort.py +379 -0
  128. microEye/hardware/stages/elliptec/deviceStatus.py +65 -0
  129. microEye/hardware/stages/elliptec/devicesView.py +706 -0
  130. microEye/hardware/stages/elliptec/ellDevices.py +134 -0
  131. microEye/hardware/stages/elliptec/messageUpdater.py +34 -0
  132. microEye/hardware/stages/elliptec/motorInfo.py +153 -0
  133. microEye/hardware/stages/elliptec/stage.py +62 -0
  134. microEye/hardware/stages/elliptec/test.py +139 -0
  135. microEye/hardware/stages/kinesis/__init__.py +1 -0
  136. microEye/hardware/stages/kinesis/kdc101/__init__.py +1 -0
  137. microEye/hardware/stages/kinesis/kdc101/enums.py +1002 -0
  138. microEye/hardware/stages/kinesis/kdc101/factory.py +171 -0
  139. microEye/hardware/stages/kinesis/kdc101/kdc101.py +718 -0
  140. microEye/hardware/stages/kinesis/kinesis.py +776 -0
  141. microEye/hardware/stages/piezo_concept.py +607 -0
  142. microEye/hardware/stages/stabilizer.py +785 -0
  143. microEye/hardware/stages/stage.py +89 -0
  144. microEye/hardware/widgets/__init__.py +10 -0
  145. microEye/hardware/widgets/controller.py +246 -0
  146. microEye/hardware/widgets/devices.py +133 -0
  147. microEye/hardware/widgets/focusWidget.py +264 -0
  148. microEye/hardware/widgets/qlist_slider.py +113 -0
  149. microEye/hardware/widgets/scan_acquisition.py +424 -0
  150. microEye/icons/1024.png +0 -0
  151. microEye/icons/128.png +0 -0
  152. microEye/icons/16.png +0 -0
  153. microEye/icons/24.png +0 -0
  154. microEye/icons/256.png +0 -0
  155. microEye/icons/32.png +0 -0
  156. microEye/icons/48.png +0 -0
  157. microEye/icons/512.png +0 -0
  158. microEye/icons/64.png +0 -0
  159. microEye/icons/__init__.py +0 -0
  160. microEye/icons/close.svg +88 -0
  161. microEye/icons/mieye.png +0 -0
  162. microEye/icons/min.svg +83 -0
  163. microEye/icons/viewer.png +0 -0
  164. microEye/launcher.py +42 -0
  165. microEye/qt.py +181 -0
  166. microEye/utils/__init__.py +2 -0
  167. microEye/utils/enum_encoder.py +10 -0
  168. microEye/utils/expandable_groupbox.py +93 -0
  169. microEye/utils/gui_helper.py +457 -0
  170. microEye/utils/hid/__init__.py +8 -0
  171. microEye/utils/hid/controller.py +153 -0
  172. microEye/utils/hid/device.py +63 -0
  173. microEye/utils/hid/enums.py +140 -0
  174. microEye/utils/hid/utils.py +58 -0
  175. microEye/utils/labelled_slider.py +134 -0
  176. microEye/utils/metadata.py +599 -0
  177. microEye/utils/metadata_tree.py +718 -0
  178. microEye/utils/micro_launcher.py +245 -0
  179. microEye/utils/parameter_tree.py +325 -0
  180. microEye/utils/pyscripting.py +444 -0
  181. microEye/utils/retry_exec.py +35 -0
  182. microEye/utils/start_gui.py +112 -0
  183. microEye/utils/thread_worker.py +115 -0
  184. microEye/utils/uImage.py +1512 -0
  185. microeye-2.3.2.dist-info/METADATA +401 -0
  186. microeye-2.3.2.dist-info/RECORD +190 -0
  187. microeye-2.3.2.dist-info/WHEEL +5 -0
  188. microeye-2.3.2.dist-info/entry_points.txt +2 -0
  189. microeye-2.3.2.dist-info/licenses/LICENSE +674 -0
  190. 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
+ )