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,264 @@
1
+ import json
2
+
3
+ import numpy as np
4
+ import pyqtgraph as pg
5
+ from pyqtgraph.widgets.PlotWidget import PlotItem, PlotWidget
6
+ from pyqtgraph.widgets.RemoteGraphicsView import RemoteGraphicsView
7
+
8
+ from microEye.hardware.stages.stabilizer import *
9
+ from microEye.qt import QtWidgets
10
+ from microEye.utils.gui_helper import GaussianOffSet
11
+
12
+
13
+ class focusWidget(QtWidgets.QDockWidget):
14
+ def __init__(self):
15
+ '''
16
+ Initialize the focusWidget instance.
17
+
18
+ Set up the GUI layout, including the ROI settings, buttons, and graph widgets.
19
+ '''
20
+ super().__init__('Focus Stabilization')
21
+
22
+ # Remove close button from dock widgets
23
+ self.setFeatures(
24
+ QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetFloatable
25
+ | QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable
26
+ )
27
+
28
+ self.focusStabilizerView = FocusStabilizerView()
29
+
30
+ self.init_layout()
31
+
32
+ self.connectUpdateGui()
33
+
34
+ self.focusStabilizerView.setRoiActivated.connect(self.set_roi)
35
+
36
+ # We need to store a reference to the plotted line
37
+ # somewhere, so we can apply the new data to it.
38
+ self.__plot_ref = None
39
+ self.__plotfit_ref = None
40
+ self.__center_ref = None
41
+
42
+ def init_layout(self):
43
+ # display tab
44
+ self.labelStyle = {'color': '#FFF', 'font-size': '10pt'}
45
+ graphs_layout = QtWidgets.QGridLayout()
46
+
47
+ # Graphics Layout
48
+ self.graphicsLayoutWidget = pg.GraphicsLayoutWidget()
49
+ graphicsLayout = self.graphicsLayoutWidget.ci
50
+ pg.setConfigOptions(antialias=True, imageAxisOrder='row-major')
51
+ pg.setConfigOption('imageAxisOrder', 'row-major')
52
+
53
+ # IR Camera GraphView
54
+ self.remote_plt = graphicsLayout.addViewBox(0, 0, invertY=True)
55
+ self.remote_plt.setAspectLocked()
56
+ self.remote_img = pg.ImageItem(axisOrder='row-major')
57
+ self.remote_img.setImage(np.random.normal(size=(512, 512)))
58
+ # IR LineROI
59
+ self.roi = pg.ROI(pg.Point(25.5, 25.5), pg.Point(0, 256), angle=0, pen='r')
60
+ self.roi.addTranslateHandle([0, 0], [0, 1])
61
+ self.roi.addScaleRotateHandle([0, 1], [0, 0])
62
+ self.roi.updateFlag = False
63
+
64
+ # IR LineROI Graph
65
+ self.graph_IR = graphicsLayout.addPlot(1, 0)
66
+ self.graph_IR.setLabel('bottom', 'Pixel', **self.labelStyle)
67
+ self.graph_IR.setLabel('left', 'Signal', 'V', **self.labelStyle)
68
+ # IR Peak Position Graph
69
+ self.graph_Peak = graphicsLayout.addPlot(2, 0)
70
+ self.graph_Peak.setLabel('bottom', 'Frame', **self.labelStyle)
71
+ self.graph_Peak.setLabel('left', 'Center Pixel Error', **self.labelStyle)
72
+
73
+ # self.roi.maxBounds = QRectF(0, 0, 513, 513)
74
+ def roiChanged(cls):
75
+ if not self.roi.updateFlag:
76
+ pos = self.roi.pos()
77
+ self.focusStabilizerView.set_param_value(
78
+ FocusStabilizerParams.X1, pos[0]
79
+ )
80
+ self.focusStabilizerView.set_param_value(
81
+ FocusStabilizerParams.Y1, pos[1]
82
+ )
83
+ self.focusStabilizerView.set_param_value(
84
+ FocusStabilizerParams.LENGTH, self.roi.size()[1]
85
+ )
86
+ self.focusStabilizerView.set_param_value(
87
+ FocusStabilizerParams.ANGLE, self.roi.angle() % 360
88
+ )
89
+ x, y = self.getRoiCoords()
90
+ self.focusStabilizerView.set_param_value(FocusStabilizerParams.X2, x[1])
91
+ self.focusStabilizerView.set_param_value(FocusStabilizerParams.Y2, y[1])
92
+ if self.roi.size()[0] > 0:
93
+ self.roi.setSize((0, self.roi.size()[1]))
94
+
95
+ # self.lr_proxy = pg.multiprocess.proxy(
96
+ # roiChanged, callSync='off', autoProxy=True)
97
+ self.roi.sigRegionChangeFinished.connect(roiChanged)
98
+ self.remote_plt.addItem(self.remote_img)
99
+ self.remote_plt.addItem(self.roi)
100
+
101
+ graphs_layout.addWidget(self.graphicsLayoutWidget, 0, 1, 3, 1)
102
+ graphs_layout.addWidget(self.focusStabilizerView, 0, 3)
103
+
104
+ container = QtWidgets.QWidget(self)
105
+ container.setLayout(graphs_layout)
106
+ self.setWidget(container)
107
+
108
+ @property
109
+ def buffer(self):
110
+ return FocusStabilizer.instance().buffer
111
+
112
+ def connectUpdateGui(self):
113
+ FocusStabilizer.instance().updateViewBox.connect(self.updateViewBox)
114
+ FocusStabilizer.instance().updatePlots.connect(self.updatePlots)
115
+
116
+ def updateViewBox(self, data: np.ndarray):
117
+ self.remote_img.setImage(data, _callSync='off')
118
+
119
+ def updatePlots(self, data):
120
+ '''Updates the graphs.'''
121
+ xdata = np.arange(len(data))
122
+ # updates the IR graph with data
123
+ if self.__plot_ref is None:
124
+ # create plot reference when None
125
+ self.__plot_ref = self.graph_IR.plot(xdata, data)
126
+ else:
127
+ # use the plot reference to update the data for that line.
128
+ self.__plot_ref.setData(xdata, data)
129
+
130
+ if self.__center_ref is None:
131
+ # create plot reference when None
132
+ self.__center_ref = self.graph_Peak.plot(
133
+ FocusStabilizer.instance().peak_time,
134
+ FocusStabilizer.instance().peak_positions,
135
+ )
136
+ else:
137
+ # use the plot reference to update the data for that line.
138
+ self.__center_ref.setData(
139
+ FocusStabilizer.instance().peak_time,
140
+ FocusStabilizer.instance().peak_positions,
141
+ )
142
+
143
+ if FocusStabilizer.instance().fit_params is None:
144
+ # no fit params available, so return
145
+ return
146
+
147
+ # updates the IR graph with data fit
148
+ if self.__plotfit_ref is None:
149
+ # create plot reference when None
150
+ self.__plotfit_ref = self.graph_IR.plot(
151
+ xdata, GaussianOffSet(xdata, *FocusStabilizer.instance().fit_params)
152
+ )
153
+ else:
154
+ # use the plot reference to update the data for that line.
155
+ self.__plotfit_ref.setData(
156
+ xdata, GaussianOffSet(xdata, *FocusStabilizer.instance().fit_params)
157
+ )
158
+
159
+ def updateRoiParams(self, params: dict):
160
+ if 'ROI_x' in params:
161
+ self.focusStabilizerView.set_param_value(
162
+ FocusStabilizerParams.X1, float(params['ROI_x'])
163
+ )
164
+ if 'ROI_y' in params:
165
+ self.focusStabilizerView.set_param_value(
166
+ FocusStabilizerParams.Y1, float(params['ROI_y'])
167
+ )
168
+ if 'ROI_length' in params:
169
+ self.focusStabilizerView.set_param_value(
170
+ FocusStabilizerParams.LENGTH, int(params['ROI_length'])
171
+ )
172
+ if 'ROI_angle' in params:
173
+ self.focusStabilizerView.set_param_value(
174
+ FocusStabilizerParams.ANGLE, float(params['ROI_angle'])
175
+ )
176
+ if 'ROI_Width' in params:
177
+ self.focusStabilizerView.set_param_value(
178
+ FocusStabilizerParams.LINE_WIDTH, int(params['ROI_Width'])
179
+ )
180
+ x, y = self.getRoiCoords()
181
+ self.focusStabilizerView.set_param_value(FocusStabilizerParams.X2, x[1])
182
+ self.focusStabilizerView.set_param_value(FocusStabilizerParams.Y2, y[1])
183
+
184
+ if 'PixelCalCoeff' in params:
185
+ self.focusStabilizerView.set_param_value(
186
+ FocusStabilizerParams.PIXEL_CAL, float(params['PixelCalCoeff'])
187
+ )
188
+ if 'UseCal' in params:
189
+ self.focusStabilizerView.set_param_value(
190
+ FocusStabilizerParams.USE_CAL, bool(params['UseCal'])
191
+ )
192
+ if 'Inverted' in params:
193
+ self.focusStabilizerView.set_param_value(
194
+ FocusStabilizerParams.INVERTED, bool(params['Inverted'])
195
+ )
196
+ if 'PID' in params:
197
+ _P, _I, _D, _tau, _err_th = params['PID']
198
+ self.focusStabilizerView.set_param_value(
199
+ FocusStabilizerParams.FT_P, float(_P)
200
+ )
201
+ self.focusStabilizerView.set_param_value(
202
+ FocusStabilizerParams.FT_I, float(_I)
203
+ )
204
+ self.focusStabilizerView.set_param_value(
205
+ FocusStabilizerParams.FT_D, float(_D)
206
+ )
207
+ self.focusStabilizerView.set_param_value(
208
+ FocusStabilizerParams.FT_TAU, float(_tau)
209
+ )
210
+ self.focusStabilizerView.set_param_value(
211
+ FocusStabilizerParams.FT_ERROR_TH, float(_err_th)
212
+ )
213
+
214
+ def getRoiCoords(self):
215
+ dy = self.roi.state['size'][1] * np.cos(np.pi * self.roi.state['angle'] / 180)
216
+ dx = self.roi.state['size'][1] * np.sin(np.pi * self.roi.state['angle'] / 180)
217
+ x = self.roi.x()
218
+ y = self.roi.y()
219
+ return [x, x - dx], [y, y + dy]
220
+
221
+ def set_roi(self):
222
+ '''
223
+ Set the ROI based on the current spin box values.
224
+ '''
225
+ self.roi.updateFlag = True
226
+ self.roi.setPos(
227
+ self.focusStabilizerView.get_param_value(FocusStabilizerParams.X1),
228
+ self.focusStabilizerView.get_param_value(FocusStabilizerParams.Y1),
229
+ )
230
+ self.roi.setSize(
231
+ [0, self.focusStabilizerView.get_param_value(FocusStabilizerParams.LENGTH)]
232
+ )
233
+ self.roi.setAngle(
234
+ self.focusStabilizerView.get_param_value(FocusStabilizerParams.ANGLE)
235
+ )
236
+
237
+ x, y = self.getRoiCoords()
238
+ self.focusStabilizerView.set_param_value(FocusStabilizerParams.X2, x[1])
239
+ self.focusStabilizerView.set_param_value(FocusStabilizerParams.Y2, y[1])
240
+
241
+ self.roi.updateFlag = False
242
+
243
+ def get_config(self) -> dict:
244
+ return {
245
+ 'ROI_x': self.roi.x(),
246
+ 'ROI_y': self.roi.y(),
247
+ 'ROI_length': self.roi.state['size'][1],
248
+ 'ROI_angle': self.roi.state['angle'] % 360,
249
+ 'ROI_Width': FocusStabilizer.instance().line_width,
250
+ 'PID': FocusStabilizer.instance().getPID(),
251
+ 'PixelCalCoeff': FocusStabilizer.instance().pixelCalCoeff(),
252
+ 'UseCal': FocusStabilizer.instance().useCal(),
253
+ 'Inverted': FocusStabilizer.instance().isInverted(),
254
+ }
255
+
256
+ def load_config(self, config: dict) -> None:
257
+ if not isinstance(config, dict):
258
+ raise TypeError('Configuration must be a dictionary.')
259
+
260
+ self.updateRoiParams(config)
261
+ self.set_roi()
262
+
263
+ def __str__(self):
264
+ return 'Focus Stabilization Widget'
@@ -0,0 +1,113 @@
1
+ import numpy as np
2
+
3
+ from microEye.qt import QApplication, Qt, QtCore, QtGui, QtWidgets, Signal, Slot
4
+
5
+
6
+ class QListSlider(QtWidgets.QSlider):
7
+ '''QList Slider
8
+
9
+ Inherits QSlider allows selecting over a range of
10
+ non-integer values using a slider using indecies.
11
+
12
+ Parameters
13
+ ----------
14
+ values : list | ndarray
15
+ list or array of values.
16
+ '''
17
+ elementChanged = Signal([int, int], [int, float])
18
+ '''Element changed Signal,
19
+ supports (index: int, value: int) or (index: int, value: float) functions.
20
+ '''
21
+
22
+ def __init__(self, values=None, *args, **kwargs):
23
+ super().__init__(*args, **kwargs)
24
+ self.setMinimum(0)
25
+ self._values = []
26
+ self.valueChanged.connect(self._on_value_changed)
27
+ self.values = values or []
28
+
29
+ @property
30
+ def values(self):
31
+ '''Gets values property.
32
+
33
+ Returns
34
+ -------
35
+ list | ndarray
36
+ list or array of values.
37
+ '''
38
+ return self._values
39
+
40
+ @values.setter
41
+ def values(self, values):
42
+ '''Sets values property.
43
+
44
+ Parameters
45
+ ----------
46
+ values : list | ndarray
47
+ list or array of values.
48
+ '''
49
+ self._values = values
50
+ maximum = max(0, len(self._values) - 1)
51
+ self.setMaximum(maximum)
52
+ self.setValue(0)
53
+
54
+ @Slot(int)
55
+ def _on_value_changed(self, index):
56
+ '''On value changed emits the element changed signal.
57
+
58
+ Parameters
59
+ ----------
60
+ index : int
61
+ the selected element index.
62
+ '''
63
+ value = self.values[index]
64
+ self.elementChanged[int, int].emit(index, value)
65
+ self.elementChanged[int, float].emit(index, value)
66
+
67
+ def find_nearest(self, array, value):
68
+ '''
69
+ find nearest value in array to the supplied one
70
+
71
+ Parameters
72
+ ----------
73
+ array : ndarray
74
+ numpy array searching in
75
+ value : type of ndarray.dtype
76
+ value to find nearest to in the array
77
+ '''
78
+ array = np.asarray(array)
79
+ return (np.abs(array - value)).argmin()
80
+
81
+ def setNearest(self, value):
82
+ self.setValue(self.find_nearest(
83
+ self.values,
84
+ float(value)))
85
+
86
+
87
+ class DragLabel(QtWidgets.QLabel):
88
+ def __init__(self, parent=None, parent_name: str = ''):
89
+ super(QtWidgets.QLabel, self).__init__(parent)
90
+ self.parent_name = parent_name
91
+ self.show()
92
+
93
+ def mousePressEvent(self, event):
94
+ if event.button() == Qt.LeftButton:
95
+ self.drag_start_position = event.pos()
96
+
97
+ def mouseMoveEvent(self, event):
98
+ if not (event.buttons() & Qt.LeftButton):
99
+ return
100
+ if (event.pos() - self.drag_start_position).manhattanLength() < \
101
+ QApplication.startDragDistance():
102
+ return
103
+ drag = QtGui.QDrag(self)
104
+ mimedata = QtCore.QMimeData()
105
+ mimedata.setText(self.parent_name)
106
+ drag.setMimeData(mimedata)
107
+ pixmap = QtGui.QPixmap(self.size())
108
+ painter = QtGui.QPainter(pixmap)
109
+ painter.drawPixmap(self.rect(), self.grab())
110
+ painter.end()
111
+ drag.setPixmap(pixmap)
112
+ drag.setHotSpot(event.pos())
113
+ drag.exec_(Qt.CopyAction | Qt.MoveAction)