microeye 2.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- microEye/__init__.py +47 -0
- microEye/_version.py +2 -0
- microEye/analysis/__init__.py +1 -0
- microEye/analysis/checklist_dialog.py +143 -0
- microEye/analysis/cmosMaps.py +228 -0
- microEye/analysis/filters/__init__.py +9 -0
- microEye/analysis/filters/base.py +21 -0
- microEye/analysis/filters/spatial.py +338 -0
- microEye/analysis/filters/temporal.py +76 -0
- microEye/analysis/fitting/__init__.py +0 -0
- microEye/analysis/fitting/fit.py +680 -0
- microEye/analysis/fitting/nena.py +375 -0
- microEye/analysis/fitting/phasor_fit.py +90 -0
- microEye/analysis/fitting/processing.py +317 -0
- microEye/analysis/fitting/psf/__init__.py +6 -0
- microEye/analysis/fitting/psf/extract.py +1129 -0
- microEye/analysis/fitting/psf/rubost_mean.py +150 -0
- microEye/analysis/fitting/psf/spline.py +167 -0
- microEye/analysis/fitting/psf/stats/__init__.py +12 -0
- microEye/analysis/fitting/psf/stats/core.py +295 -0
- microEye/analysis/fitting/psf/stats/curve_fit.py +708 -0
- microEye/analysis/fitting/psf/stats/io.py +104 -0
- microEye/analysis/fitting/psf/stats/slope_fit.py +171 -0
- microEye/analysis/fitting/psf/temp.py +147 -0
- microEye/analysis/fitting/psf/test.py +47 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUfunctions.py +657 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUmleFit_LM.py +1336 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUsplineLib.py +270 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/__init__.py +1 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUfunctions.py +609 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_EMCCD.py +1396 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_sCMOS.py +1426 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUsplineLib.py +231 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/__init__.py +2 -0
- microEye/analysis/fitting/pyfit3Dcspline/__init__.py +10 -0
- microEye/analysis/fitting/pyfit3Dcspline/constants.py +27 -0
- microEye/analysis/fitting/pyfit3Dcspline/mainfunctions.py +903 -0
- microEye/analysis/fitting/results.py +917 -0
- microEye/analysis/fitting/results_stats.py +251 -0
- microEye/analysis/fitting/tardis.py +209 -0
- microEye/analysis/multi_viewer.py +568 -0
- microEye/analysis/processing/__init__.py +1 -0
- microEye/analysis/processing/frc.py +120 -0
- microEye/analysis/rendering/__init__.py +3 -0
- microEye/analysis/rendering/base.py +452 -0
- microEye/analysis/rendering/cloud.py +215 -0
- microEye/analysis/rendering/core.py +47 -0
- microEye/analysis/rendering/volumetric.py +198 -0
- microEye/analysis/tools/__init__.py +0 -0
- microEye/analysis/tools/kymograms.py +1079 -0
- microEye/analysis/tools/roi_selectors.py +556 -0
- microEye/analysis/utils/__init__.py +3 -0
- microEye/analysis/utils/coordinates.py +18 -0
- microEye/analysis/utils/images.py +68 -0
- microEye/analysis/utils/windows.py +19 -0
- microEye/analysis/viewer/__init__.py +3 -0
- microEye/analysis/viewer/image_options_widget.py +615 -0
- microEye/analysis/viewer/images.py +1225 -0
- microEye/analysis/viewer/layers_widget.py +415 -0
- microEye/analysis/viewer/localizations.py +1304 -0
- microEye/analysis/viewer/psf.py +1003 -0
- microEye/analysis/viewer/volume.py +456 -0
- microEye/hardware/__init__.py +3 -0
- microEye/hardware/cams/__init__.py +29 -0
- microEye/hardware/cams/camera_calibration.py +99 -0
- microEye/hardware/cams/camera_list.py +528 -0
- microEye/hardware/cams/camera_options.py +694 -0
- microEye/hardware/cams/camera_panel.py +941 -0
- microEye/hardware/cams/dummy/__init__.py +1 -0
- microEye/hardware/cams/dummy/dummy_panel.py +759 -0
- microEye/hardware/cams/jobs.py +497 -0
- microEye/hardware/cams/line_profiler.py +99 -0
- microEye/hardware/cams/linescan/IR_Cam.py +474 -0
- microEye/hardware/cams/linescan/__init__.py +1 -0
- microEye/hardware/cams/micam.py +524 -0
- microEye/hardware/cams/pco/__init__.py +58 -0
- microEye/hardware/cams/pco/enums.py +382 -0
- microEye/hardware/cams/pco/pco_cam.py +761 -0
- microEye/hardware/cams/pco/pco_panel.py +477 -0
- microEye/hardware/cams/shortcuts.py +312 -0
- microEye/hardware/cams/thorlabs/__init__.py +1 -0
- microEye/hardware/cams/thorlabs/thorlabs.py +1508 -0
- microEye/hardware/cams/thorlabs/thorlabs_panel.py +850 -0
- microEye/hardware/cams/ueye/__init__.py +1 -0
- microEye/hardware/cams/ueye/ueye_camera.py +1023 -0
- microEye/hardware/cams/ueye/ueye_panel.py +861 -0
- microEye/hardware/cams/vimba/__init__.py +1 -0
- microEye/hardware/cams/vimba/vimba_cam.py +1000 -0
- microEye/hardware/cams/vimba/vimba_panel.py +813 -0
- microEye/hardware/device.py +60 -0
- microEye/hardware/lasers/__init__.py +13 -0
- microEye/hardware/lasers/io_matchbox.py +791 -0
- microEye/hardware/lasers/io_params.py +85 -0
- microEye/hardware/lasers/io_single_laser.py +742 -0
- microEye/hardware/lasers/laser_relay.py +594 -0
- microEye/hardware/mieye/__init__.py +1 -0
- microEye/hardware/mieye/acquisition_manager.py +467 -0
- microEye/hardware/mieye/devices_manager.py +533 -0
- microEye/hardware/mieye/miEye.py +659 -0
- microEye/hardware/misc/__init__.py +0 -0
- microEye/hardware/misc/acquisition_view.py +71 -0
- microEye/hardware/misc/reglo.py +761 -0
- microEye/hardware/misc/temp.py +188 -0
- microEye/hardware/port_config.py +59 -0
- microEye/hardware/protocols/__init__.py +2 -0
- microEye/hardware/protocols/actions.py +402 -0
- microEye/hardware/protocols/actions_items.py +703 -0
- microEye/hardware/protocols/designer.py +244 -0
- microEye/hardware/protocols/scene_manager.py +191 -0
- microEye/hardware/protocols/serialization.py +97 -0
- microEye/hardware/pycromanager/__init__.py +16 -0
- microEye/hardware/pycromanager/core.py +1433 -0
- microEye/hardware/pycromanager/devices.py +461 -0
- microEye/hardware/pycromanager/enums.py +107 -0
- microEye/hardware/pycromanager/headless.py +153 -0
- microEye/hardware/pycromanager/utils.py +34 -0
- microEye/hardware/pycromanager/widgets/__init__.py +5 -0
- microEye/hardware/pycromanager/widgets/bridges.py +407 -0
- microEye/hardware/pycromanager/widgets/headless_manager.py +258 -0
- microEye/hardware/pycromanager/widgets/headless_options.py +224 -0
- microEye/hardware/pycromanager/widgets/pycro_panel.py +455 -0
- microEye/hardware/stages/__init__.py +18 -0
- microEye/hardware/stages/elliptec/__init__.py +5 -0
- microEye/hardware/stages/elliptec/baseDevice.py +314 -0
- microEye/hardware/stages/elliptec/device.py +384 -0
- microEye/hardware/stages/elliptec/deviceID.py +212 -0
- microEye/hardware/stages/elliptec/devicePort.py +379 -0
- microEye/hardware/stages/elliptec/deviceStatus.py +65 -0
- microEye/hardware/stages/elliptec/devicesView.py +706 -0
- microEye/hardware/stages/elliptec/ellDevices.py +134 -0
- microEye/hardware/stages/elliptec/messageUpdater.py +34 -0
- microEye/hardware/stages/elliptec/motorInfo.py +153 -0
- microEye/hardware/stages/elliptec/stage.py +62 -0
- microEye/hardware/stages/elliptec/test.py +139 -0
- microEye/hardware/stages/kinesis/__init__.py +1 -0
- microEye/hardware/stages/kinesis/kdc101/__init__.py +1 -0
- microEye/hardware/stages/kinesis/kdc101/enums.py +1002 -0
- microEye/hardware/stages/kinesis/kdc101/factory.py +171 -0
- microEye/hardware/stages/kinesis/kdc101/kdc101.py +718 -0
- microEye/hardware/stages/kinesis/kinesis.py +776 -0
- microEye/hardware/stages/piezo_concept.py +607 -0
- microEye/hardware/stages/stabilizer.py +785 -0
- microEye/hardware/stages/stage.py +89 -0
- microEye/hardware/widgets/__init__.py +10 -0
- microEye/hardware/widgets/controller.py +246 -0
- microEye/hardware/widgets/devices.py +133 -0
- microEye/hardware/widgets/focusWidget.py +264 -0
- microEye/hardware/widgets/qlist_slider.py +113 -0
- microEye/hardware/widgets/scan_acquisition.py +424 -0
- microEye/icons/1024.png +0 -0
- microEye/icons/128.png +0 -0
- microEye/icons/16.png +0 -0
- microEye/icons/24.png +0 -0
- microEye/icons/256.png +0 -0
- microEye/icons/32.png +0 -0
- microEye/icons/48.png +0 -0
- microEye/icons/512.png +0 -0
- microEye/icons/64.png +0 -0
- microEye/icons/__init__.py +0 -0
- microEye/icons/close.svg +88 -0
- microEye/icons/mieye.png +0 -0
- microEye/icons/min.svg +83 -0
- microEye/icons/viewer.png +0 -0
- microEye/launcher.py +42 -0
- microEye/qt.py +181 -0
- microEye/utils/__init__.py +2 -0
- microEye/utils/enum_encoder.py +10 -0
- microEye/utils/expandable_groupbox.py +93 -0
- microEye/utils/gui_helper.py +457 -0
- microEye/utils/hid/__init__.py +8 -0
- microEye/utils/hid/controller.py +153 -0
- microEye/utils/hid/device.py +63 -0
- microEye/utils/hid/enums.py +140 -0
- microEye/utils/hid/utils.py +58 -0
- microEye/utils/labelled_slider.py +134 -0
- microEye/utils/metadata.py +599 -0
- microEye/utils/metadata_tree.py +718 -0
- microEye/utils/micro_launcher.py +245 -0
- microEye/utils/parameter_tree.py +325 -0
- microEye/utils/pyscripting.py +444 -0
- microEye/utils/retry_exec.py +35 -0
- microEye/utils/start_gui.py +112 -0
- microEye/utils/thread_worker.py +115 -0
- microEye/utils/uImage.py +1512 -0
- microeye-2.3.2.dist-info/METADATA +401 -0
- microeye-2.3.2.dist-info/RECORD +190 -0
- microeye-2.3.2.dist-info/WHEEL +5 -0
- microeye-2.3.2.dist-info/entry_points.txt +2 -0
- microeye-2.3.2.dist-info/licenses/LICENSE +674 -0
- microeye-2.3.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
import numba
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@numba.jit(nopython=True)
|
|
8
|
+
def render_volume_compute(data, out_volume):
|
|
9
|
+
'''
|
|
10
|
+
Compute the volumetric histogram using numba for acceleration.
|
|
11
|
+
'''
|
|
12
|
+
for x, y, z, intensity in data:
|
|
13
|
+
out_volume[int(z), int(y), int(x)] += intensity
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class VolumeRenderer:
|
|
17
|
+
'''
|
|
18
|
+
Volume renderer for rendering 3D super resolution images
|
|
19
|
+
'''
|
|
20
|
+
|
|
21
|
+
def __init__(self, xy_voxel_size=10, z_voxel_size=50):
|
|
22
|
+
'''
|
|
23
|
+
Initialize the volume renderer.
|
|
24
|
+
|
|
25
|
+
Parameters:
|
|
26
|
+
-----------
|
|
27
|
+
xy_voxel_size : float
|
|
28
|
+
Size of each voxel in the lateral (XY) dimensions
|
|
29
|
+
z_voxel_size : float
|
|
30
|
+
Size of each voxel in the axial (Z) dimension
|
|
31
|
+
'''
|
|
32
|
+
self._xy_voxel_size = xy_voxel_size
|
|
33
|
+
self._z_voxel_size = z_voxel_size
|
|
34
|
+
self._volume = None
|
|
35
|
+
|
|
36
|
+
def _validate_inputs(self, X, Y, Z, Intensity):
|
|
37
|
+
'''
|
|
38
|
+
Validate the inputs for rendering.
|
|
39
|
+
'''
|
|
40
|
+
if not len(X) == len(Y) == len(Z) == len(Intensity):
|
|
41
|
+
raise ValueError('The supplied coordinate arrays are of different lengths.')
|
|
42
|
+
|
|
43
|
+
def _normalize_xy(self, X, Y):
|
|
44
|
+
'''
|
|
45
|
+
Normalize XY coordinates to start from zero.
|
|
46
|
+
'''
|
|
47
|
+
x_min, y_min = np.min(X), np.min(Y)
|
|
48
|
+
|
|
49
|
+
if x_min < 0:
|
|
50
|
+
X = X - x_min
|
|
51
|
+
if y_min < 0:
|
|
52
|
+
Y = Y - y_min
|
|
53
|
+
|
|
54
|
+
return X, Y
|
|
55
|
+
|
|
56
|
+
def render(self, X, Y, Z, Intensity, shape=None):
|
|
57
|
+
"""
|
|
58
|
+
Generates a volumetric histogram from 3D single-molecule localizations.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
-----------
|
|
62
|
+
X : np.ndarray
|
|
63
|
+
Array of X coordinates for the localizations.
|
|
64
|
+
Y : np.ndarray
|
|
65
|
+
Array of Y coordinates for the localizations.
|
|
66
|
+
Z : np.ndarray
|
|
67
|
+
Array of Z coordinates for the localizations (preserving the zero reference)
|
|
68
|
+
Intensity : np.ndarray
|
|
69
|
+
Array of intensity values corresponding to each localization.
|
|
70
|
+
shape : tuple[int, int, int], optional
|
|
71
|
+
Dimensions of the volume as (depth, height, width). Defaults to None.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
--------
|
|
75
|
+
np.ndarray
|
|
76
|
+
3D volume array suitable for visualization
|
|
77
|
+
metadata : dict
|
|
78
|
+
Dictionary containing voxel sizes and coordinate ranges
|
|
79
|
+
- 'voxel_size' (dict): Voxel sizes in each dimension ('x', 'y', 'z').
|
|
80
|
+
- 'coordinates' (dict): Z-coordinate range ('z_min', 'z_max').
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
self._validate_inputs(X, Y, Z, Intensity)
|
|
84
|
+
X, Y = self._normalize_xy(X, Y)
|
|
85
|
+
|
|
86
|
+
if shape is None:
|
|
87
|
+
# Calculate XY dimensions based on data extent
|
|
88
|
+
x_max = int((np.max(X) / self._xy_voxel_size) + 4)
|
|
89
|
+
y_max = int((np.max(Y) / self._xy_voxel_size) + 4)
|
|
90
|
+
|
|
91
|
+
# Calculate Z dimension to maintain zero reference
|
|
92
|
+
z_min = int(np.floor(np.min(Z) / self._z_voxel_size)) - 2
|
|
93
|
+
z_max = int(np.ceil(np.max(Z) / self._z_voxel_size)) + 2
|
|
94
|
+
z_size = z_max - z_min
|
|
95
|
+
|
|
96
|
+
shape = (z_size, y_max, x_max)
|
|
97
|
+
|
|
98
|
+
self._volume = np.zeros(shape)
|
|
99
|
+
|
|
100
|
+
# Convert XY coordinates to voxel space (positive-only indices)
|
|
101
|
+
X_voxels = X / self._xy_voxel_size + 2
|
|
102
|
+
Y_voxels = Y / self._xy_voxel_size + 2
|
|
103
|
+
|
|
104
|
+
# Convert Z coordinates to voxel space maintaining zero reference
|
|
105
|
+
z_min = int(np.floor(np.min(Z) / self._z_voxel_size)) - 2
|
|
106
|
+
Z_voxels = Z / self._z_voxel_size - z_min
|
|
107
|
+
|
|
108
|
+
render_volume_compute(
|
|
109
|
+
np.c_[X_voxels, Y_voxels, Z_voxels, Intensity], self._volume
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Return metadata for proper scaling and positioning in visualization
|
|
113
|
+
metadata = {
|
|
114
|
+
'voxel_size': {
|
|
115
|
+
'x': self._xy_voxel_size,
|
|
116
|
+
'y': self._xy_voxel_size,
|
|
117
|
+
'z': self._z_voxel_size,
|
|
118
|
+
},
|
|
119
|
+
'coordinates': {
|
|
120
|
+
'z_min': z_min
|
|
121
|
+
* self._z_voxel_size, # actual z coordinate where volume starts
|
|
122
|
+
'z_max': (z_min + shape[0])
|
|
123
|
+
* self._z_voxel_size, # actual z coordinate where volume ends
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return self._volume, metadata
|
|
128
|
+
|
|
129
|
+
def from_array(self, data: np.ndarray, shape=None):
|
|
130
|
+
'''
|
|
131
|
+
Renders a volumetric histogram from an array of localizations.
|
|
132
|
+
|
|
133
|
+
Parameters:
|
|
134
|
+
-----------
|
|
135
|
+
data : np.ndarray
|
|
136
|
+
Array with columns (X, Y, Z, Intensity)
|
|
137
|
+
shape : tuple[int, int, int], optional
|
|
138
|
+
Volume dimensions (depth, height, width), by default None
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
--------
|
|
142
|
+
np.ndarray
|
|
143
|
+
3D volume array suitable for visualization
|
|
144
|
+
metadata : dict
|
|
145
|
+
Dictionary containing voxel sizes and coordinate ranges
|
|
146
|
+
'''
|
|
147
|
+
return self.render(data[:, 0], data[:, 1], data[:, 2], data[:, 3], shape)
|
|
148
|
+
|
|
149
|
+
def normalize_volume(volume_data: np.ndarray):
|
|
150
|
+
'''
|
|
151
|
+
Normalize volume data to range [0,1] using Numba acceleration.
|
|
152
|
+
'''
|
|
153
|
+
# data_min = np.min(volume_data)
|
|
154
|
+
# data_max = np.max(volume_data)
|
|
155
|
+
q1, q3 = np.nanpercentile(volume_data[volume_data > 0], [1, 99])
|
|
156
|
+
return (np.clip(volume_data, q1, q3) - q1) / (q3 - q1)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@numba.jit(nopython=True, parallel=True)
|
|
160
|
+
def create_rgba_volume(normalized_data, colors, opacity):
|
|
161
|
+
'''
|
|
162
|
+
Create RGBA volume with colormap using Numba acceleration.
|
|
163
|
+
|
|
164
|
+
Parameters:
|
|
165
|
+
-----------
|
|
166
|
+
normalized_data : np.ndarray
|
|
167
|
+
3D array of normalized data values (0-1)
|
|
168
|
+
colors : np.ndarray
|
|
169
|
+
256x3 array of RGB colors for the colormap
|
|
170
|
+
opacity : float
|
|
171
|
+
Global opacity multiplier (0-1)
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
--------
|
|
175
|
+
rgba_volume : np.ndarray
|
|
176
|
+
4D array containing the RGBA volume
|
|
177
|
+
'''
|
|
178
|
+
shape = normalized_data.shape
|
|
179
|
+
rgba_volume = np.empty(shape + (4,), dtype=np.uint8)
|
|
180
|
+
|
|
181
|
+
# Convert normalized data to color indices
|
|
182
|
+
color_indices = (normalized_data * 255).astype(np.uint8)
|
|
183
|
+
|
|
184
|
+
# Fill RGB channels
|
|
185
|
+
for i in numba.prange(shape[0]):
|
|
186
|
+
for j in range(shape[1]):
|
|
187
|
+
for k in range(shape[2]):
|
|
188
|
+
idx = color_indices[i, j, k]
|
|
189
|
+
rgba_volume[i, j, k, 0] = colors[idx, 0] # Red
|
|
190
|
+
rgba_volume[i, j, k, 1] = colors[idx, 1] # Green
|
|
191
|
+
rgba_volume[i, j, k, 2] = colors[idx, 2] # Blue
|
|
192
|
+
# Alpha channel with opacity scaling
|
|
193
|
+
rgba_volume[i, j, k, 3] = min(
|
|
194
|
+
255, int(normalized_data[i, j, k] * 255 * opacity)
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
return rgba_volume
|
|
198
|
+
|
|
File without changes
|