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
microEye/__init__.py ADDED
@@ -0,0 +1,47 @@
1
+ from microEye._version import __version__, version_info
2
+
3
+
4
+ def getArgs():
5
+ import argparse
6
+ import os
7
+ import sys
8
+
9
+ parser = argparse.ArgumentParser()
10
+ parser.add_argument(
11
+ '--module',
12
+ help='The module to launch [mieye|viewer], '
13
+ + 'If not specified, launcher is executed.',
14
+ choices=['mieye', 'viewer']
15
+ )
16
+ parser.add_argument(
17
+ '--QT_API',
18
+ help='Select QT API [PySide6|PyQT6|PyQt5], '
19
+ + 'If not specified, the environment variable QT_API is used.',
20
+ choices=['PySide6', 'PyQt6', 'PyQt5']
21
+ )
22
+ parser.add_argument(
23
+ '--theme',
24
+ help='The theme of the app, '
25
+ + 'if not specified, the environment variable MITHEME is used.',
26
+ choices=['None', 'qdarktheme', 'qdarkstyle', '...']
27
+ )
28
+
29
+ args, _ = parser.parse_known_args(sys.argv)
30
+
31
+ # access the parsed arguments
32
+ if args.QT_API:
33
+ os.environ['QT_API'] = args.QT_API
34
+ os.environ['PYQTGRAPH_QT_LIB'] = args.QT_API
35
+
36
+ if args.theme:
37
+ os.environ['MITHEME'] = args.theme
38
+
39
+ return args
40
+
41
+
42
+ ARGS = getArgs()
43
+
44
+ import microEye.analysis.fitting.pyfit3Dcspline as pyfit3Dcspline # noqa: E402
45
+ from microEye.analysis import multi_viewer # noqa: E402
46
+ from microEye.hardware import miEye_module # noqa: E402
47
+ from microEye.qt import * # noqa: I001, E402
microEye/_version.py ADDED
@@ -0,0 +1,2 @@
1
+ version_info = (2, 3, 2)
2
+ __version__ = '.'.join(map(str, version_info))
@@ -0,0 +1 @@
1
+ from microEye.analysis.multi_viewer import multi_viewer
@@ -0,0 +1,143 @@
1
+
2
+ from microEye.qt import Qt, QtGui, QtWidgets
3
+
4
+
5
+ class ChecklistDialog(QtWidgets.QDialog):
6
+
7
+ def __init__(
8
+ self,
9
+ name,
10
+ stringlist=None,
11
+ checked=False,
12
+ icon=None,
13
+ parent=None,
14
+ ):
15
+ super().__init__(parent)
16
+
17
+ self.name = name
18
+ self.icon = icon
19
+ self.model = QtGui.QStandardItemModel()
20
+ self.listView = QtWidgets.QListView()
21
+
22
+ for string in stringlist:
23
+ item = QtGui.QStandardItem(string)
24
+ item.setCheckable(True)
25
+ check = \
26
+ (Qt.CheckState.Checked if checked else Qt.CheckState.Unchecked)
27
+ item.setCheckState(check)
28
+ self.model.appendRow(item)
29
+
30
+ self.listView.setModel(self.model)
31
+
32
+ self.export_precision = QtWidgets.QLineEdit('%10.5f')
33
+
34
+ self.okButton = QtWidgets.QPushButton('OK')
35
+ self.cancelButton = QtWidgets.QPushButton('Cancel')
36
+ self.selectButton = QtWidgets.QPushButton('Select All')
37
+ self.unselectButton = QtWidgets.QPushButton('Unselect All')
38
+
39
+ hbox = QtWidgets.QHBoxLayout()
40
+ hbox.addStretch(1)
41
+ hbox.addWidget(self.okButton)
42
+ hbox.addWidget(self.cancelButton)
43
+ hbox.addWidget(self.selectButton)
44
+ hbox.addWidget(self.unselectButton)
45
+
46
+ vbox = QtWidgets.QFormLayout(self)
47
+ vbox.addRow(self.listView)
48
+ vbox.addRow(
49
+ QtWidgets.QLabel('Format:'), self.export_precision)
50
+ vbox.addRow(hbox)
51
+
52
+ self.setWindowTitle(self.name)
53
+ if self.icon:
54
+ self.setWindowIcon(self.icon)
55
+
56
+ self.okButton.clicked.connect(self.onAccepted)
57
+ self.cancelButton.clicked.connect(self.reject)
58
+ self.selectButton.clicked.connect(self.select)
59
+ self.unselectButton.clicked.connect(self.unselect)
60
+
61
+ def onAccepted(self):
62
+ self.choices = self.toList()
63
+ self.accept()
64
+
65
+ def select(self):
66
+ for i in range(self.model.rowCount()):
67
+ item = self.model.item(i)
68
+ item.setCheckState(Qt.CheckState.Checked)
69
+
70
+ def unselect(self):
71
+ for i in range(self.model.rowCount()):
72
+ item = self.model.item(i)
73
+ item.setCheckState(Qt.CheckState.Unchecked)
74
+
75
+ def toList(self):
76
+ return [self.model.item(i).text() for i in
77
+ range(self.model.rowCount())
78
+ if self.model.item(i).checkState()
79
+ == Qt.CheckState.Checked]
80
+
81
+
82
+ class Checklist(QtWidgets.QGroupBox):
83
+
84
+ def __init__(
85
+ self,
86
+ name,
87
+ stringlist=None,
88
+ checked=False,
89
+ parent=None,
90
+ ):
91
+ super(QtWidgets.QGroupBox, self).__init__(parent)
92
+
93
+ self.name = name
94
+ self.model = QtGui.QStandardItemModel()
95
+ self.listView = QtWidgets.QListView()
96
+
97
+ for _, string in enumerate(stringlist):
98
+ item = QtGui.QStandardItem(string)
99
+ item.setCheckable(True)
100
+ check = \
101
+ (Qt.Checked if checked else Qt.Unchecked)
102
+ item.setCheckState(check)
103
+ self.model.appendRow(item)
104
+
105
+ self.listView.setModel(self.model)
106
+
107
+ self.okButton = QtWidgets.QPushButton('OK')
108
+ self.cancelButton = QtWidgets.QPushButton('Cancel')
109
+ self.selectButton = QtWidgets.QPushButton('Select All')
110
+ self.unselectButton = QtWidgets.QPushButton('Unselect All')
111
+
112
+ hbox = QtWidgets.QHBoxLayout()
113
+ hbox.addStretch(1)
114
+ hbox.addWidget(self.okButton)
115
+ hbox.addWidget(self.cancelButton)
116
+ hbox.addWidget(self.selectButton)
117
+ hbox.addWidget(self.unselectButton)
118
+
119
+ vbox = QtWidgets.QVBoxLayout(self)
120
+ vbox.addWidget(self.listView)
121
+ vbox.addStretch(1)
122
+ vbox.addLayout(hbox)
123
+
124
+ self.setTitle(self.name)
125
+
126
+ self.selectButton.clicked.connect(self.select)
127
+ self.unselectButton.clicked.connect(self.unselect)
128
+
129
+ def toList(self):
130
+ return [self.model.item(i).text() for i in
131
+ range(self.model.rowCount())
132
+ if self.model.item(i).checkState()
133
+ == Qt.CheckState.Checked]
134
+
135
+ def select(self):
136
+ for i in range(self.model.rowCount()):
137
+ item = self.model.item(i)
138
+ item.setCheckState(Qt.CheckState.Checked)
139
+
140
+ def unselect(self):
141
+ for i in range(self.model.rowCount()):
142
+ item = self.model.item(i)
143
+ item.setCheckState(Qt.CheckState.Unchecked)
@@ -0,0 +1,228 @@
1
+ import typing
2
+
3
+ import numpy as np
4
+ import tifffile as tf
5
+
6
+ from microEye.qt import QtWidgets, getExistingDirectory, getOpenFileName
7
+
8
+
9
+ class cmosMaps(QtWidgets.QWidget):
10
+ def __init__(self, parent: typing.Optional['QtWidgets.QWidget'] = None):
11
+ super().__init__(parent=parent)
12
+
13
+ self.invGain = None
14
+ self.baseline = None
15
+ self.darkCurrent = None
16
+ self.readNoiseSQ = None
17
+ self.thermalNoiseSQ = None
18
+ self.expTime = 100.00699
19
+
20
+ self.offsetMap = None
21
+ self.varMap = None
22
+
23
+ self.InitLayout()
24
+
25
+ def InitLayout(self):
26
+ self.main_layout = QtWidgets.QFormLayout(self)
27
+
28
+ self.setLayout(self.main_layout)
29
+
30
+ self.invg_le = QtWidgets.QLineEdit()
31
+ self.baseline_le = QtWidgets.QLineEdit()
32
+ self.darkc_le = QtWidgets.QLineEdit()
33
+ self.readnsq_le = QtWidgets.QLineEdit()
34
+ self.thermnsq_le = QtWidgets.QLineEdit()
35
+
36
+ self.invg_le.setReadOnly(True)
37
+ self.baseline_le.setReadOnly(True)
38
+ self.darkc_le.setReadOnly(True)
39
+ self.readnsq_le.setReadOnly(True)
40
+ self.thermnsq_le.setReadOnly(True)
41
+
42
+ self.invg_btn = QtWidgets.QPushButton('open', clicked=lambda: self.browseImg(0))
43
+ self.baseline_btn = QtWidgets.QPushButton(
44
+ 'open', clicked=lambda: self.browseImg(1)
45
+ )
46
+ self.darkc_btn = QtWidgets.QPushButton(
47
+ 'open', clicked=lambda: self.browseImg(2)
48
+ )
49
+ self.readnsq_btn = QtWidgets.QPushButton(
50
+ 'open', clicked=lambda: self.browseImg(3)
51
+ )
52
+ self.thermnsq_btn = QtWidgets.QPushButton(
53
+ 'open', clicked=lambda: self.browseImg(4)
54
+ )
55
+
56
+ self.main_layout.addRow(QtWidgets.QLabel('inverse Gain map:'), self.invg_le)
57
+ self.main_layout.addWidget(self.invg_btn)
58
+ self.main_layout.addRow(
59
+ QtWidgets.QLabel('Baseline map [ADU]:'), self.baseline_le
60
+ )
61
+ self.main_layout.addWidget(self.baseline_btn)
62
+ self.main_layout.addRow(
63
+ QtWidgets.QLabel('Dark current map [ADU/s]:'), self.darkc_le
64
+ )
65
+ self.main_layout.addWidget(self.darkc_btn)
66
+ self.main_layout.addRow(
67
+ QtWidgets.QLabel('Read noise sq map [ADU^2]:'), self.readnsq_le
68
+ )
69
+ self.main_layout.addWidget(self.readnsq_btn)
70
+ self.main_layout.addRow(
71
+ QtWidgets.QLabel('Thermal noise sq map [ADU^2/s]:'), self.thermnsq_le
72
+ )
73
+ self.main_layout.addWidget(self.thermnsq_btn)
74
+
75
+ self.exp_spin = QtWidgets.QDoubleSpinBox()
76
+ self.exp_spin.setMinimum(0)
77
+ self.exp_spin.setMaximum(10000)
78
+ self.exp_spin.setDecimals(5)
79
+ self.exp_spin.setValue(self.expTime)
80
+
81
+ self.main_layout.addRow(QtWidgets.QLabel('Exposure [ms]:'), self.exp_spin)
82
+
83
+ self.calc_btn = QtWidgets.QPushButton(
84
+ 'gen. offset / var maps', clicked=lambda: self.calcMaps()
85
+ )
86
+
87
+ self.main_layout.addWidget(self.calc_btn)
88
+
89
+ self.X = QtWidgets.QSpinBox()
90
+ self.Y = QtWidgets.QSpinBox()
91
+ self.W = QtWidgets.QSpinBox()
92
+ self.H = QtWidgets.QSpinBox()
93
+ self.X.setMinimum(0)
94
+ self.Y.setMinimum(0)
95
+ self.W.setMinimum(0)
96
+ self.H.setMinimum(0)
97
+ self.X.setMaximum(10000)
98
+ self.Y.setMaximum(10000)
99
+ self.W.setMaximum(10000)
100
+ self.H.setMaximum(10000)
101
+
102
+ self.main_layout.addRow(QtWidgets.QLabel('ROI X:'), self.X)
103
+ self.main_layout.addRow(QtWidgets.QLabel('ROI Y:'), self.Y)
104
+ self.main_layout.addRow(QtWidgets.QLabel('ROI Width:'), self.W)
105
+ self.main_layout.addRow(QtWidgets.QLabel('ROI Height:'), self.H)
106
+
107
+ self.active = QtWidgets.QCheckBox('Use Maps?')
108
+ self.active.setChecked(False)
109
+ self.gain = QtWidgets.QCheckBox('Use Gain?')
110
+ self.gain.setChecked(False)
111
+
112
+ self.main_layout.addWidget(self.active)
113
+ self.main_layout.addWidget(self.gain)
114
+
115
+ def browseImg(self, index):
116
+ filename, _ = getOpenFileName(
117
+ self, 'Load Image', filter='Tiff Image Files (*.tif);'
118
+ )
119
+
120
+ if len(filename) > 0:
121
+ img = tf.imread(filename)
122
+ self.H.setValue(img.shape[0])
123
+ self.W.setValue(img.shape[1])
124
+
125
+ if index == 0:
126
+ self.invg_le.setText(filename)
127
+ self.invg_le.setToolTip(str(img.shape))
128
+ self.invGain = img
129
+ elif index == 1:
130
+ self.baseline_le.setText(filename)
131
+ self.baseline_le.setToolTip(str(img.shape))
132
+ self.baseline = img
133
+ elif index == 2:
134
+ self.darkc_le.setText(filename)
135
+ self.darkc_le.setToolTip(str(img.shape))
136
+ self.darkCurrent = img
137
+ elif index == 3:
138
+ self.readnsq_le.setText(filename)
139
+ self.readnsq_le.setToolTip(str(img.shape))
140
+ self.readNoiseSQ = img
141
+ elif index == 4:
142
+ self.thermnsq_le.setText(filename)
143
+ self.thermnsq_le.setToolTip(str(img.shape))
144
+ self.thermalNoiseSQ = img
145
+
146
+ def missingMap(self):
147
+ print('Missing Maps!')
148
+
149
+ def calcMaps(self, export=True):
150
+ if self.invGain is None:
151
+ self.missingMap()
152
+ return False
153
+ if self.baseline is None:
154
+ self.missingMap()
155
+ return False
156
+ if self.darkCurrent is None:
157
+ self.missingMap()
158
+ return False
159
+ if self.readNoiseSQ is None:
160
+ self.missingMap()
161
+ return False
162
+ if self.thermalNoiseSQ is None:
163
+ self.missingMap()
164
+ return False
165
+
166
+ shapes = []
167
+ shapes.append(self.invGain.shape)
168
+ shapes.append(self.baseline.shape)
169
+ shapes.append(self.darkCurrent.shape)
170
+ shapes.append(self.readNoiseSQ.shape)
171
+ shapes.append(self.thermalNoiseSQ.shape)
172
+ shapes = np.vstack(shapes)
173
+
174
+ if not np.all(shapes[:, 0] == shapes[0, 0]) or not np.all(
175
+ shapes[:, 1] == shapes[0, 1]
176
+ ):
177
+ print('Maps have unmatching dimensions!')
178
+ return False
179
+
180
+ self.expTime = self.exp_spin.value()
181
+
182
+ offsetMap = self.baseline + self.expTime * self.darkCurrent
183
+
184
+ varMap = self.readNoiseSQ + self.expTime * self.thermalNoiseSQ
185
+
186
+ if self.gain.isChecked():
187
+ self.offsetMap = offsetMap * self.invGain
188
+ self.varMap = varMap * np.square(self.invGain)
189
+ else:
190
+ self.offsetMap = offsetMap
191
+ self.varMap = varMap
192
+
193
+ if not export:
194
+ return True
195
+
196
+ _directory = str(getExistingDirectory(self, 'Select Directory'))
197
+
198
+ if len(_directory) < 1:
199
+ return
200
+
201
+ tf.imwrite(
202
+ _directory + f'/offset_{self.expTime:.5f}ms'.replace('.', '_') + '.tif',
203
+ self.offsetMap,
204
+ )
205
+ tf.imwrite(
206
+ _directory + f'/var_{self.expTime:.5f}ms'.replace('.', '_') + '.tif',
207
+ self.varMap,
208
+ )
209
+
210
+ return True
211
+
212
+ def getMaps(self):
213
+ if self.calcMaps(False):
214
+ x = self.X.value()
215
+ y = self.Y.value()
216
+ w = self.W.value()
217
+ h = self.H.value()
218
+
219
+ offset = self.offsetMap[y : y + h, x : x + w]
220
+ var = self.varMap[y : y + h, x : x + w]
221
+
222
+ if self.gain.isChecked():
223
+ gain = self.invGain[y : y + h, x : x + w]
224
+ else:
225
+ gain = np.ones_like(offset)
226
+ return gain, offset, var
227
+ else:
228
+ return None
@@ -0,0 +1,9 @@
1
+ from microEye.analysis.filters.base import AbstractFilter
2
+ from microEye.analysis.filters.spatial import (
3
+ BANDPASS_TYPES,
4
+ BandpassFilter,
5
+ DoG_Filter,
6
+ GaussFilter,
7
+ PassFilter,
8
+ )
9
+ from microEye.analysis.filters.temporal import TemporalMedianFilter
@@ -0,0 +1,21 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ import numpy as np
4
+ from PyQt5 import QtWidgets
5
+
6
+
7
+ class AbstractFilter(ABC):
8
+ @abstractmethod
9
+ def run(self, image: np.ndarray) -> np.ndarray:
10
+ '''Apply the filter to the input image.'''
11
+ pass
12
+
13
+ def getWidget(self):
14
+ '''Return the QWidget for configuring the filter.'''
15
+ return QtWidgets.QWidget()
16
+
17
+ def get_metadata(self) -> dict:
18
+ '''Return metadata about the filter.'''
19
+ return {
20
+ 'name': 'Abstract Base Filter'
21
+ }