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,850 @@
1
+ import json
2
+ import traceback
3
+ from enum import Enum
4
+
5
+ from microEye.analysis.tools.roi_selectors import (
6
+ MultiRectangularROISelector,
7
+ convert_pos_size_to_rois,
8
+ convert_rois_to_pos_size,
9
+ )
10
+ from microEye.hardware.cams.camera_options import CamParams
11
+ from microEye.hardware.cams.camera_panel import Camera_Panel
12
+ from microEye.hardware.cams.thorlabs.thorlabs import (
13
+ CMD,
14
+ FLASH_MODE,
15
+ IS_DONT_WAIT,
16
+ TRIGGER,
17
+ thorlabs_camera,
18
+ )
19
+ from microEye.qt import (
20
+ QDateTime,
21
+ QtCore,
22
+ QtWidgets,
23
+ Slot,
24
+ getOpenFileName,
25
+ getSaveFileName,
26
+ )
27
+ from microEye.utils.gui_helper import get_scaling_factor
28
+ from microEye.utils.metadata_tree import MetaParams
29
+ from microEye.utils.thread_worker import QThreadWorker
30
+ from microEye.utils.uImage import uImage
31
+
32
+
33
+ class ThorCamParams(Enum):
34
+ FREERUN = 'Acquisition.Start (Freerun)'
35
+ TRIGGERED = 'Acquisition.Start (Triggered)'
36
+ STOP = 'Acquisition.Stop'
37
+ PIXEL_CLOCK = 'Acquisition Settings.Pixel Clock (MHz)'
38
+ FRAMERATE = 'Acquisition Settings.Framerate Slider'
39
+ FRAME_AVERAGING = 'Acquisition Settings.Frame Averaging'
40
+ TRIGGER_MODE = 'Acquisition Settings.Trigger Mode'
41
+ FLASH_MODE = 'Acquisition Settings.Flash Mode'
42
+ FLASH_DURATION = 'Acquisition Settings.Flash Duration Slider'
43
+ FLASH_DELAY = 'Acquisition Settings.Flash Delay Slider'
44
+ LOAD = 'Acquisition Settings.Load'
45
+ SAVE = 'Acquisition Settings.Save'
46
+
47
+ def __str__(self):
48
+ '''
49
+ Return the last part of the enum value (Param name).
50
+ '''
51
+ return self.value.split('.')[-1]
52
+
53
+ def get_path(self):
54
+ '''
55
+ Return the full parameter path.
56
+ '''
57
+ return self.value.split('.')
58
+
59
+
60
+ class Thorlabs_Panel(Camera_Panel):
61
+ '''
62
+ A Qt Widget for controlling a Thorlabs Camera | Inherits Camera_Panel
63
+ '''
64
+ PARAMS = ThorCamParams
65
+
66
+ def __init__(self, cam: thorlabs_camera, mini: bool = False, *args, **kwargs):
67
+ '''
68
+ Initializes a new Thorlabs_Panel Qt widget.
69
+
70
+ Inherits Camera_Panel.
71
+
72
+ Parameters
73
+ ----------
74
+ cam : thorlabs_camera
75
+ Thorlabs Camera python adapter.
76
+
77
+ mini : bool, optional
78
+ Flag indicating if this is a mini camera panel, by default False.
79
+
80
+ Other Parameters
81
+ ---------------
82
+ *args
83
+ Arguments to pass to the Camera_Panel constructor.
84
+
85
+ **kwargs
86
+ Keyword arguments to pass to the Camera_Panel constructor.
87
+ '''
88
+ super().__init__(cam, mini, *args, **kwargs)
89
+
90
+ # flag true to close camera adapter and dispose it
91
+ self._dispose_cam = False
92
+
93
+ self.OME_tab.set_param_value(MetaParams.CHANNEL_NAME, self._cam.name)
94
+ self.OME_tab.set_param_value(MetaParams.DET_MANUFACTURER, 'Thorlabs')
95
+ self.OME_tab.set_param_value(
96
+ MetaParams.DET_MODEL, self._cam.sInfo.strSensorName.decode('utf-8')
97
+ )
98
+ self.OME_tab.set_param_value(
99
+ MetaParams.DET_SERIAL, self._cam.cInfo.SerNo.decode('utf-8')
100
+ )
101
+ self.OME_tab.set_param_value(MetaParams.DET_TYPE, 'CMOS')
102
+
103
+ # pixel clock label and combobox
104
+ pixel_clock = {
105
+ 'name': str(ThorCamParams.PIXEL_CLOCK),
106
+ 'type': 'list',
107
+ 'limits': list(map(str, self._cam.pixel_clock_list[:])),
108
+ }
109
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, pixel_clock)
110
+ self.camera_options.get_param(
111
+ ThorCamParams.PIXEL_CLOCK
112
+ ).sigValueChanged.connect(
113
+ lambda: self.cam_pixel_cbox_changed(ThorCamParams.PIXEL_CLOCK)
114
+ )
115
+
116
+ # framerate slider control
117
+ framerate = {
118
+ 'name': str(ThorCamParams.FRAMERATE),
119
+ 'type': 'float',
120
+ 'value': int(self._cam.current_framerate.value),
121
+ 'dec': False,
122
+ 'decimals': 6,
123
+ 'step': self._cam.increment_framerate.value,
124
+ 'limits': [self._cam.min_framerate.value, self._cam.max_framerate.value],
125
+ 'suffix': 'Hz',
126
+ }
127
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, framerate)
128
+ self.camera_options.get_param(ThorCamParams.FRAMERATE).sigValueChanged.connect(
129
+ self.cam_framerate_value_changed
130
+ )
131
+
132
+ # exposure text box
133
+ exposure = self.camera_options.get_param(CamParams.EXPOSURE)
134
+ exposure.setLimits((self._cam.exposure_range[0], self._cam.exposure_range[1]))
135
+ exposure.setOpts(step=self._cam.exposure_range[2], suffix='ms')
136
+ exposure.setValue(self._cam.exposure_current.value)
137
+ exposure.sigValueChanged.connect(self.exposure_spin_changed)
138
+
139
+ # trigger mode combobox
140
+ trigger_mode = {
141
+ 'name': str(ThorCamParams.TRIGGER_MODE),
142
+ 'type': 'list',
143
+ 'limits': list(TRIGGER.TRIGGER_MODES.keys()),
144
+ }
145
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, trigger_mode)
146
+ self.camera_options.get_param(
147
+ ThorCamParams.TRIGGER_MODE
148
+ ).sigValueChanged.connect(
149
+ lambda: self.cam_trigger_cbox_changed(ThorCamParams.TRIGGER_MODE)
150
+ )
151
+
152
+ # flash mode combobox
153
+ flash_mode = {
154
+ 'name': str(ThorCamParams.FLASH_MODE),
155
+ 'type': 'list',
156
+ 'limits': list(FLASH_MODE.FLASH_MODES.keys()),
157
+ 'enabled': not self.mini,
158
+ }
159
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, flash_mode)
160
+ self.camera_options.get_param(ThorCamParams.FLASH_MODE).sigValueChanged.connect(
161
+ lambda: self.cam_flash_cbox_changed(ThorCamParams.FLASH_MODE)
162
+ )
163
+
164
+ # flash duration slider
165
+ falsh_duration = {
166
+ 'name': str(ThorCamParams.FLASH_DURATION),
167
+ 'type': 'int',
168
+ 'value': 0,
169
+ 'dec': False,
170
+ 'decimals': 6,
171
+ 'suffix': 'us',
172
+ 'enabled': not self.mini,
173
+ 'step': self._cam.flash_inc.u32Duration,
174
+ 'limits': [0, self._cam.flash_max.u32Duration],
175
+ }
176
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, falsh_duration)
177
+ self.camera_options.get_param(
178
+ ThorCamParams.FLASH_DURATION
179
+ ).sigValueChanged.connect(self.cam_flash_duration_value_changed)
180
+
181
+ # flash delay
182
+ falsh_delay = {
183
+ 'name': str(ThorCamParams.FLASH_DELAY),
184
+ 'type': 'int',
185
+ 'value': 0,
186
+ 'dec': False,
187
+ 'decimals': 6,
188
+ 'suffix': 'us',
189
+ 'enabled': not self.mini,
190
+ 'step': self._cam.flash_inc.s32Delay,
191
+ 'limits': [0, self._cam.flash_max.s32Delay],
192
+ }
193
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, falsh_delay)
194
+ self.camera_options.get_param(
195
+ ThorCamParams.FLASH_DELAY
196
+ ).sigValueChanged.connect(self.cam_flash_delay_value_changed)
197
+
198
+ # setting the highest pixel clock as default
199
+ self.camera_options.set_param_value(
200
+ ThorCamParams.PIXEL_CLOCK, str(self._cam.pixel_clock_list[-1])
201
+ )
202
+
203
+ # start freerun mode
204
+ freerun = self.get_event_action(ThorCamParams.FREERUN)
205
+ self.camera_options.add_param_child(CamParams.ACQUISITION, freerun)
206
+ self.camera_options.get_param(ThorCamParams.FREERUN).sigActivated.connect(
207
+ self.start_free_run
208
+ )
209
+
210
+ # start trigger mode button
211
+ triggered = self.get_event_action(ThorCamParams.TRIGGERED)
212
+ self.camera_options.add_param_child(CamParams.ACQUISITION, triggered)
213
+ self.camera_options.get_param(ThorCamParams.TRIGGERED).sigActivated.connect(
214
+ self.start_software_triggered
215
+ )
216
+
217
+ # stop acquisition
218
+ stop = {'name': str(ThorCamParams.STOP), 'type': 'action'}
219
+ self.camera_options.add_param_child(CamParams.ACQUISITION, stop)
220
+ self.camera_options.get_param(ThorCamParams.STOP).sigActivated.connect(
221
+ lambda: self.stop()
222
+ )
223
+
224
+ # config buttons
225
+ load = {'name': str(ThorCamParams.LOAD), 'type': 'action'}
226
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, load)
227
+ self.camera_options.get_param(ThorCamParams.LOAD).sigActivated.connect(
228
+ lambda: self.load_config()
229
+ )
230
+
231
+ save = {'name': str(ThorCamParams.SAVE), 'type': 'action'}
232
+ self.camera_options.add_param_child(CamParams.ACQ_SETTINGS, save)
233
+ self.camera_options.get_param(ThorCamParams.SAVE).sigActivated.connect(
234
+ lambda: self.save_config()
235
+ )
236
+
237
+ # ROI
238
+ self.camera_options.set_roi_limits(
239
+ (0, self.cam.rectROI.s32Width),
240
+ (0, self.cam.rectROI.s32Height),
241
+ (32, self.cam.rectROI.s32Width),
242
+ (32, self.cam.rectROI.s32Height),
243
+ )
244
+
245
+ @property
246
+ def cam(self):
247
+ '''The thorlabs_camera property.
248
+
249
+ Returns
250
+ -------
251
+ thorlabs_camera
252
+ the cam property value
253
+ '''
254
+ return self._cam
255
+
256
+ @cam.setter
257
+ def cam(self, cam: thorlabs_camera):
258
+ '''The thorlabs_camera property.
259
+
260
+ Parameters
261
+ ----------
262
+ cam : thorlabs_camera
263
+ the thorlabs_camera to set as panel camera.
264
+ '''
265
+ self._cam = cam
266
+
267
+ def set_ROI(self):
268
+ '''Sets the ROI for the slected thorlabs_camera'''
269
+ if self.cam.acquisition:
270
+ QtWidgets.QMessageBox.warning(
271
+ self, 'Warning', 'Cannot set ROI while acquiring images!'
272
+ )
273
+ return # if acquisition is already going on
274
+
275
+ self.cam.set_roi(*self.camera_options.get_roi_info())
276
+
277
+ # setting the highest pixel clock as default
278
+ self.camera_options.set_param_value(
279
+ ThorCamParams.PIXEL_CLOCK, str(self._cam.pixel_clock_list[0])
280
+ )
281
+ self.camera_options.set_param_value(
282
+ ThorCamParams.PIXEL_CLOCK, str(self._cam.pixel_clock_list[-1])
283
+ )
284
+
285
+ self.camera_options.set_roi_info(
286
+ self.cam.set_rectROI.s32X,
287
+ self.cam.set_rectROI.s32Y,
288
+ self.cam.set_rectROI.s32Width,
289
+ self.cam.set_rectROI.s32Height,
290
+ )
291
+
292
+ def reset_ROI(self):
293
+ '''Resets the ROI for the slected thorlabs_camera'''
294
+ if self.cam.acquisition:
295
+ QtWidgets.QMessageBox.warning(
296
+ self, 'Warning', 'Cannot reset ROI while acquiring images!'
297
+ )
298
+ return # if acquisition is already going on
299
+
300
+ self.cam.reset_roi()
301
+ self.camera_options.set_roi_info(0, 0, self.cam.width, self.cam.height)
302
+
303
+ # setting the highest pixel clock as default
304
+ self.camera_options.set_param_value(
305
+ ThorCamParams.PIXEL_CLOCK, str(self._cam.pixel_clock_list[0])
306
+ )
307
+ self.camera_options.set_param_value(
308
+ ThorCamParams.PIXEL_CLOCK, str(self._cam.pixel_clock_list[-1])
309
+ )
310
+
311
+ def center_ROI(self):
312
+ '''Calculates the x, y values for a centered ROI'''
313
+ if self.cam.acquisition:
314
+ QtWidgets.QMessageBox.warning(
315
+ self, 'Warning', 'Cannot center ROI while acquiring images!'
316
+ )
317
+ return # if acquisition is already going on
318
+
319
+ _, _, w, h = self.camera_options.get_roi_info()
320
+ x = (self.cam.rectROI.s32Width - w) // 2
321
+ y = (self.cam.rectROI.s32Height - h) // 2
322
+
323
+ self.camera_options.set_roi_info(x, y, w, h)
324
+
325
+ self.set_ROI()
326
+
327
+ def select_ROI(self):
328
+ '''
329
+ Opens a dialog to select a ROI from the last image.
330
+ '''
331
+ if self.cam.acquisition:
332
+ QtWidgets.QMessageBox.warning(
333
+ self, 'Warning', 'Cannot set ROI while acquiring images!'
334
+ )
335
+ return # if acquisition is already going on
336
+
337
+ if self.acq_job.frame is not None:
338
+ try:
339
+
340
+ def work_func(**kwargs):
341
+ try:
342
+ image = uImage(self.acq_job.frame.image)
343
+
344
+ image.equalizeLUT(nLUT=True)
345
+
346
+ scale_factor = get_scaling_factor(image.height, image.width)
347
+
348
+ selector = MultiRectangularROISelector.get_selector(
349
+ image._view, scale_factor, max_rois=1
350
+ )
351
+ # if old_rois:
352
+ # selector.rois = old_rois
353
+
354
+ rois = selector.select_rectangular_rois()
355
+
356
+ rois = convert_rois_to_pos_size(rois)
357
+
358
+ if len(rois) > 0:
359
+ return rois[0]
360
+ else:
361
+ return None
362
+ except Exception:
363
+ traceback.print_exc()
364
+ return None
365
+
366
+ def done(result: list):
367
+ if result is not None:
368
+ # x, y, w, h = result
369
+ self.camera_options.set_roi_info(*result)
370
+
371
+ self.worker = QThreadWorker(work_func)
372
+ self.worker.signals.result.connect(done)
373
+ # Execute
374
+ self._threadpool.start(self.worker)
375
+ except Exception:
376
+ traceback.print_exc()
377
+
378
+ def select_ROIs(self):
379
+ '''
380
+ Opens a dialog to select multiple ROIs from the last image.
381
+ '''
382
+ if self.cam.acquisition:
383
+ QtWidgets.QMessageBox.warning(
384
+ self, 'Warning', 'Cannot reset ROI while acquiring images!'
385
+ )
386
+ return # if acquisition is already going on
387
+
388
+ if self.acq_job is not None:
389
+ try:
390
+
391
+ def work_func(**kwargs):
392
+ try:
393
+ image = uImage(self.acq_job.frame.image)
394
+
395
+ image.equalizeLUT(nLUT=True)
396
+
397
+ scale_factor = get_scaling_factor(image.height, image.width)
398
+
399
+ selector = MultiRectangularROISelector.get_selector(
400
+ image._view, scale_factor, max_rois=4, one_size=True
401
+ )
402
+
403
+ old_rois = self.camera_options.get_export_rois()
404
+
405
+ if len(old_rois) > 0:
406
+ old_rois = convert_pos_size_to_rois(old_rois)
407
+ selector.rois = old_rois
408
+
409
+ rois = selector.select_rectangular_rois()
410
+
411
+ rois = convert_rois_to_pos_size(rois)
412
+
413
+ if len(rois) > 0:
414
+ return rois
415
+ else:
416
+ return None
417
+ except Exception:
418
+ traceback.print_exc()
419
+ return None
420
+
421
+ def done(results: list[list]):
422
+ if results is not None:
423
+ rois_param = self.camera_options.get_param(
424
+ CamParams.EXPORTED_ROIS
425
+ )
426
+ rois_param.clearChildren()
427
+ for x, y, w, h in results:
428
+ self.camera_options.add_param_child(
429
+ CamParams.EXPORTED_ROIS,
430
+ {
431
+ 'name': 'ROI 1',
432
+ 'type': 'str',
433
+ 'readonly': True,
434
+ 'removable': True,
435
+ 'value': f'{x}, {y}, {w}, {h}',
436
+ },
437
+ )
438
+
439
+ self.worker = QThreadWorker(work_func)
440
+ self.worker.signals.result.connect(done)
441
+ # Execute
442
+ self._threadpool.start(self.worker)
443
+ except Exception:
444
+ traceback.print_exc()
445
+
446
+ @Slot(str)
447
+ def cam_trigger_cbox_changed(self, param: ThorCamParams):
448
+ '''
449
+ Slot for changed trigger mode
450
+
451
+ Parameters
452
+ ----------
453
+ param : ThorCamParams
454
+ parameter path to index of selected trigger mode from _TRIGGER.TRIGGER_MODES
455
+ '''
456
+ value = self.camera_options.get_param_value(param)
457
+ self._cam.set_trigger_mode(TRIGGER.TRIGGER_MODES[value])
458
+ self._cam.get_trigger_mode()
459
+
460
+ @Slot(str)
461
+ def cam_flash_cbox_changed(self, param: ThorCamParams):
462
+ '''
463
+ Slot for changed flash mode
464
+
465
+ Parameters
466
+ ----------
467
+ param : ThorCamParams
468
+ parameter path to index of selected flash mode from _TRIGGER.FLASH_MODES
469
+ '''
470
+ value = self.camera_options.get_param_value(param)
471
+ self._cam.set_flash_mode(FLASH_MODE.FLASH_MODES[value])
472
+ self._cam.get_flash_mode(output=True)
473
+
474
+ @Slot(str)
475
+ def cam_pixel_cbox_changed(self, param: ThorCamParams):
476
+ '''
477
+ Slot for changed pixel clock
478
+
479
+ Parameters
480
+ ----------
481
+ param : ThorCamParams
482
+ parameter path to selected pixel clock in MHz
483
+ (note that only certain values are allowed by camera)
484
+ '''
485
+ value = self.camera_options.get_param_value(param)
486
+ self._cam.set_pixel_clock(int(value))
487
+ self._cam.get_pixel_clock_info(False)
488
+
489
+ self.refresh_framerate(True)
490
+
491
+ def cam_framerate_value_changed(self, param, value):
492
+ '''
493
+ Slot for changed framerate
494
+
495
+ Parameters
496
+ ----------
497
+ param : Parameter
498
+ frames per second parameter
499
+ Value : double
500
+ selected frames per second
501
+ '''
502
+ self._cam.set_framerate(value)
503
+
504
+ self.camera_options.set_param_value(
505
+ ThorCamParams.FRAMERATE,
506
+ self._cam.current_framerate.value,
507
+ self.cam_framerate_value_changed,
508
+ )
509
+
510
+ self.refresh_exposure()
511
+
512
+ def exposure_spin_changed(self, param, value):
513
+ '''
514
+ Slot for changed exposure
515
+
516
+ Parameters
517
+ ----------
518
+ param : Parameter
519
+ exposure parameter
520
+ Value : double
521
+ selected exposure in milliseconds
522
+ '''
523
+ self._cam.set_exposure(value)
524
+ self._cam.get_exposure(False)
525
+
526
+ self.camera_options.set_param_value(
527
+ CamParams.EXPOSURE,
528
+ self._cam.exposure_current.value,
529
+ self.exposure_spin_changed,
530
+ )
531
+
532
+ self.refresh_flash()
533
+
534
+ self.OME_tab.set_param_value(MetaParams.EXPOSURE, self._cam.exposure_current)
535
+ if self.master:
536
+ self.exposureChanged.emit()
537
+
538
+ def refresh_framerate(self, range=False):
539
+ self._cam.get_framerate_range(False)
540
+
541
+ framerate = self.camera_options.get_param(ThorCamParams.FRAMERATE)
542
+ framerate.setLimits(
543
+ (self._cam.min_framerate.value, self._cam.max_framerate.value)
544
+ )
545
+ framerate.setOpts(step=self._cam.increment_framerate.value)
546
+
547
+ self.cam_framerate_value_changed(framerate, self._cam.max_framerate.value)
548
+
549
+ def refresh_exposure(self, range=False):
550
+ self._cam.get_exposure_range(False)
551
+
552
+ exposure = self.camera_options.get_param(CamParams.EXPOSURE)
553
+ exposure.setLimits((self._cam.exposure_range[0], self._cam.exposure_range[1]))
554
+ exposure.setOpts(step=self._cam.exposure_range[2])
555
+ exposure.setValue(self.cam.exposure_range[1])
556
+
557
+ def refresh_flash(self):
558
+ self._cam.get_flash_range(False)
559
+
560
+ duration = self.camera_options.get_param(ThorCamParams.FLASH_DURATION)
561
+ duration.setLimits((0, self._cam.flash_max.u32Duration))
562
+ duration.setOpts(step=self._cam.flash_inc.u32Duration)
563
+ duration.setValue(0)
564
+
565
+ delay = self.camera_options.get_param(ThorCamParams.FLASH_DURATION)
566
+ delay.setLimits((0, self._cam.flash_max.s32Delay))
567
+ delay.setOpts(step=self._cam.flash_inc.s32Delay)
568
+ delay.setValue(0)
569
+
570
+ def cam_flash_duration_value_changed(self, param, value):
571
+ '''
572
+ Slot for changed flash duration
573
+
574
+ Parameters
575
+ ----------
576
+ param : Parameter
577
+ flash duration parameter
578
+ Value : double
579
+ selected flash duration in micro-seconds
580
+ '''
581
+ self._cam.set_flash_params(self._cam.flash_cur.s32Delay, value)
582
+ self._cam.get_flash_params()
583
+
584
+ self.camera_options.set_param_value(
585
+ ThorCamParams.FLASH_DURATION,
586
+ self._cam.flash_cur.u32Duration,
587
+ self.cam_flash_duration_value_changed,
588
+ )
589
+
590
+ def cam_flash_delay_value_changed(self, param, value):
591
+ '''
592
+ Slot for changed flash delay
593
+
594
+ Parameters
595
+ ----------
596
+ param : Parameter
597
+ flash delay parameter
598
+ Value : double
599
+ selected flash delay in micro-seconds
600
+ '''
601
+ self._cam.set_flash_params(value, self._cam.flash_cur.u32Duration)
602
+
603
+ self.camera_options.set_param_value(
604
+ ThorCamParams.FLASH_DELAY,
605
+ self._cam.flash_cur.s32Delay,
606
+ self.cam_flash_delay_value_changed,
607
+ )
608
+
609
+ def start_free_run(self, Prefix=''):
610
+ '''
611
+ Starts free run acquisition mode
612
+
613
+ Parameters
614
+ ----------
615
+ cam : IDS_Camera
616
+ IDS Camera python adapter
617
+ '''
618
+ nRet = 0
619
+ if self._cam.acquisition:
620
+ return # if acquisition is already going on
621
+
622
+ if not self._cam.memory_allocated:
623
+ self._cam.allocate_memory_buffer() # allocate memory
624
+
625
+ if not self._cam.capture_video:
626
+ self._cam.start_live_capture() # start live capture (freerun mode)
627
+
628
+ self._cam.refresh_info() # refresh adapter info
629
+
630
+ self._save_prefix = Prefix
631
+ self.acq_job = self.getAcquisitionJob()
632
+
633
+ self._cam.acquisition = True # set acquisition flag to true
634
+
635
+ # start both capture and display workers
636
+ self.start_all_workers()
637
+
638
+ def start_software_triggered(self, Prefix=''):
639
+ '''
640
+ Starts trigger acquisition mode
641
+
642
+ Parameters
643
+ ----------
644
+ cam : IDS_Camera
645
+ IDS Camera python adapter
646
+ '''
647
+
648
+ nRet = 0
649
+ if self._cam.acquisition:
650
+ return # if acquisition is already going on
651
+
652
+ if not self._cam.memory_allocated:
653
+ self._cam.allocate_memory_buffer() # allocate memory
654
+
655
+ self._cam.refresh_info() # refresh adapter info
656
+
657
+ self._save_prefix = Prefix
658
+ self.acq_job = self.getAcquisitionJob()
659
+
660
+ self._cam.acquisition = True # set acquisition flag to true
661
+
662
+ # start both capture and display workers
663
+ self.start_all_workers()
664
+
665
+ def cam_capture(self, *args, **kwargs):
666
+ '''Capture function executed by the capture worker.
667
+
668
+ Sends software trigger signals and transfers the
669
+ acquired frame to the display processing stack.
670
+
671
+ Parameters
672
+ ----------
673
+ nRet : int
674
+ return code from thorlabs_camera, ueye.IS_SUCCESS = 0 to run.
675
+ cam : thorlabs_camera
676
+ the thorlabs_camera used to acquire frames.
677
+ '''
678
+ try:
679
+ nRet = 0
680
+ time = QDateTime.currentDateTime()
681
+ # Continuous image capture
682
+ while nRet == 0:
683
+ self.acq_job.capture_time = time.msecsTo(QDateTime.currentDateTime())
684
+ time = QDateTime.currentDateTime()
685
+
686
+ if not self._cam.capture_video:
687
+ self._cam.uc480.is_FreezeVideo(self._cam.hCam, IS_DONT_WAIT)
688
+
689
+ nRet = self._cam.wait_for_next_image(500, not self.mini)
690
+ if nRet == CMD.IS_SUCCESS:
691
+ self._cam.get_pitch()
692
+ data = self._cam.get_data()
693
+
694
+ # if not np.array_equal(temp, data):
695
+ self._buffer.put(data.copy())
696
+ # add sensor temperature to the stack
697
+ self._temps.put(self._cam.get_temperature())
698
+ self.acq_job.frames_captured = self.acq_job.frames_captured + 1
699
+ if (
700
+ self.acq_job.frames_captured >= self.acq_job.frames
701
+ and not self.mini
702
+ ):
703
+ self._stop_thread = True
704
+ self._cam.unlock_buffer()
705
+
706
+ QtCore.QThread.usleep(100) # sleep 100us
707
+
708
+ if self.acq_job.stop_threads:
709
+ break # in case stop threads is initiated
710
+ except Exception:
711
+ traceback.print_exc()
712
+ finally:
713
+ # reset flags and release resources
714
+ self._cam.acquisition = False
715
+ if self._cam.capture_video:
716
+ self._cam.stop_live_capture()
717
+ self._cam.free_memory()
718
+ if self._dispose_cam:
719
+ self._cam.dispose()
720
+
721
+ def getCaptureArgs(self) -> list:
722
+ '''User specific arguments to be passed to the parallelized
723
+ Camera_Panel.cam_capture function.
724
+
725
+ Example
726
+ ------
727
+ check child panels (vimba, ueye or thorlabs)
728
+
729
+ Returns
730
+ -------
731
+ list
732
+ list of args to be passed in order to
733
+ Camera_Panel.cam_capture function.
734
+
735
+ Raises
736
+ ------
737
+ NotImplementedError
738
+ Has to be implemented by the use in child class.
739
+ '''
740
+ args = []
741
+ return args
742
+
743
+ def save_config(self):
744
+ filename, _ = getSaveFileName(
745
+ self, 'Save config', filter='JSON Files (*.json);;'
746
+ )
747
+
748
+ if len(filename) > 0:
749
+ config = {
750
+ 'model': self.cam.sInfo.strSensorName.decode('utf-8'),
751
+ 'serial': self.cam.cInfo.SerNo.decode('utf-8'),
752
+ 'clock speed': self.cam.pixel_clock.value,
753
+ 'trigger': self.camera_options.get_param_value(
754
+ ThorCamParams.TRIGGER_MODE
755
+ ),
756
+ 'flash mode': self.camera_options.get_param_value(
757
+ ThorCamParams.FLASH_MODE
758
+ ),
759
+ 'framerate': self.cam.current_framerate.value,
760
+ 'exposure': self.cam.exposure_current.value,
761
+ 'flash duration': self.cam.flash_cur.u32Duration,
762
+ 'flash delay': self.cam.flash_cur.s32Delay,
763
+ 'ROI w': self.cam.set_rectROI.s32Width,
764
+ 'ROI h': self.cam.set_rectROI.s32Height,
765
+ 'ROI x': self.cam.set_rectROI.s32X,
766
+ 'ROI y': self.cam.set_rectROI.s32Y,
767
+ 'Zoom': self.camera_options.get_param_value(CamParams.RESIZE_DISPLAY),
768
+ }
769
+
770
+ with open(filename, 'w') as file:
771
+ json.dump(config, file)
772
+
773
+ QtWidgets.QMessageBox.information(self, 'Info', 'Config saved.')
774
+ else:
775
+ QtWidgets.QMessageBox.warning(self, 'Warning', 'Config not saved.')
776
+
777
+ def load_config(self):
778
+ filename, _ = getOpenFileName(
779
+ self, 'Load config', filter='JSON Files (*.json);;'
780
+ )
781
+
782
+ if len(filename) > 0:
783
+ config: dict = None
784
+ keys = [
785
+ 'model',
786
+ 'serial',
787
+ 'clock speed',
788
+ 'trigger',
789
+ 'flash mode',
790
+ 'framerate',
791
+ 'exposure',
792
+ 'flash duration',
793
+ 'flash delay',
794
+ 'ROI w',
795
+ 'ROI h',
796
+ 'ROI x',
797
+ 'ROI y',
798
+ 'Zoom',
799
+ ]
800
+ with open(filename) as file:
801
+ config = json.load(file)
802
+ if all(key in config for key in keys):
803
+ if self.cam.sInfo.strSensorName.decode('utf-8') == config['model']:
804
+ self.camera_options.set_roi_info(
805
+ int(config['ROI x']),
806
+ int(config['ROI y']),
807
+ int(config['ROI w']),
808
+ int(config['ROI h']),
809
+ )
810
+ self.set_ROI()
811
+
812
+ self.camera_options.set_param_value(
813
+ ThorCamParams.PIXEL_CLOCK, str(config['clock speed'])
814
+ )
815
+ self.camera_options.set_param_value(
816
+ ThorCamParams.TRIGGER_MODE, config['trigger']
817
+ )
818
+ self.camera_options.set_param_value(
819
+ ThorCamParams.FLASH_DURATION, config['flash mode']
820
+ )
821
+
822
+ self.camera_options.set_param_value(
823
+ ThorCamParams.FRAMERATE, config['framerate']
824
+ )
825
+
826
+ self.camera_options.set_param_value(
827
+ CamParams.EXPOSURE, config['exposure']
828
+ )
829
+
830
+ self.camera_options.set_param_value(
831
+ ThorCamParams.FLASH_DURATION, config['flash duration']
832
+ )
833
+
834
+ self.camera_options.set_param_value(
835
+ ThorCamParams.FLASH_DELAY, config['flash delay']
836
+ )
837
+
838
+ self.camera_options.set_param_value(
839
+ CamParams.RESIZE_DISPLAY, float(config['Zoom'])
840
+ )
841
+ else:
842
+ QtWidgets.QMessageBox.warning(
843
+ self, 'Warning', 'Camera model is different.'
844
+ )
845
+ else:
846
+ QtWidgets.QMessageBox.warning(
847
+ self, 'Warning', 'Wrong or corrupted config file.'
848
+ )
849
+ else:
850
+ QtWidgets.QMessageBox.warning(self, 'Warning', 'No file selected.')