celldetective 1.4.1.post1__py3-none-any.whl → 1.5.0b0__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.
- celldetective/__init__.py +25 -0
- celldetective/__main__.py +62 -43
- celldetective/_version.py +1 -1
- celldetective/extra_properties.py +477 -399
- celldetective/filters.py +192 -97
- celldetective/gui/InitWindow.py +541 -411
- celldetective/gui/__init__.py +0 -15
- celldetective/gui/about.py +44 -39
- celldetective/gui/analyze_block.py +120 -84
- celldetective/gui/base/__init__.py +0 -0
- celldetective/gui/base/channel_norm_generator.py +335 -0
- celldetective/gui/base/components.py +249 -0
- celldetective/gui/base/feature_choice.py +92 -0
- celldetective/gui/base/figure_canvas.py +52 -0
- celldetective/gui/base/list_widget.py +133 -0
- celldetective/gui/{styles.py → base/styles.py} +92 -36
- celldetective/gui/base/utils.py +33 -0
- celldetective/gui/base_annotator.py +900 -767
- celldetective/gui/classifier_widget.py +642 -554
- celldetective/gui/configure_new_exp.py +777 -671
- celldetective/gui/control_panel.py +635 -524
- celldetective/gui/dynamic_progress.py +449 -0
- celldetective/gui/event_annotator.py +2023 -1662
- celldetective/gui/generic_signal_plot.py +1292 -944
- celldetective/gui/gui_utils.py +899 -1289
- celldetective/gui/interactions_block.py +658 -0
- celldetective/gui/interactive_timeseries_viewer.py +447 -0
- celldetective/gui/json_readers.py +48 -15
- celldetective/gui/layouts/__init__.py +5 -0
- celldetective/gui/layouts/background_model_free_layout.py +537 -0
- celldetective/gui/layouts/channel_offset_layout.py +134 -0
- celldetective/gui/layouts/local_correction_layout.py +91 -0
- celldetective/gui/layouts/model_fit_layout.py +372 -0
- celldetective/gui/layouts/operation_layout.py +68 -0
- celldetective/gui/layouts/protocol_designer_layout.py +96 -0
- celldetective/gui/pair_event_annotator.py +3130 -2435
- celldetective/gui/plot_measurements.py +586 -267
- celldetective/gui/plot_signals_ui.py +724 -506
- celldetective/gui/preprocessing_block.py +395 -0
- celldetective/gui/process_block.py +1678 -1831
- celldetective/gui/seg_model_loader.py +580 -473
- celldetective/gui/settings/__init__.py +0 -7
- celldetective/gui/settings/_cellpose_model_params.py +181 -0
- celldetective/gui/settings/_event_detection_model_params.py +95 -0
- celldetective/gui/settings/_segmentation_model_params.py +159 -0
- celldetective/gui/settings/_settings_base.py +77 -65
- celldetective/gui/settings/_settings_event_model_training.py +752 -526
- celldetective/gui/settings/_settings_measurements.py +1133 -964
- celldetective/gui/settings/_settings_neighborhood.py +574 -488
- celldetective/gui/settings/_settings_segmentation_model_training.py +779 -564
- celldetective/gui/settings/_settings_signal_annotator.py +329 -305
- celldetective/gui/settings/_settings_tracking.py +1304 -1094
- celldetective/gui/settings/_stardist_model_params.py +98 -0
- celldetective/gui/survival_ui.py +422 -312
- celldetective/gui/tableUI.py +1665 -1700
- celldetective/gui/table_ops/_maths.py +295 -0
- celldetective/gui/table_ops/_merge_groups.py +140 -0
- celldetective/gui/table_ops/_merge_one_hot.py +95 -0
- celldetective/gui/table_ops/_query_table.py +43 -0
- celldetective/gui/table_ops/_rename_col.py +44 -0
- celldetective/gui/thresholds_gui.py +382 -179
- celldetective/gui/viewers/__init__.py +0 -0
- celldetective/gui/viewers/base_viewer.py +700 -0
- celldetective/gui/viewers/channel_offset_viewer.py +331 -0
- celldetective/gui/viewers/contour_viewer.py +394 -0
- celldetective/gui/viewers/size_viewer.py +153 -0
- celldetective/gui/viewers/spot_detection_viewer.py +341 -0
- celldetective/gui/viewers/threshold_viewer.py +309 -0
- celldetective/gui/workers.py +304 -126
- celldetective/log_manager.py +92 -0
- celldetective/measure.py +1895 -1478
- celldetective/napari/__init__.py +0 -0
- celldetective/napari/utils.py +1025 -0
- celldetective/neighborhood.py +1914 -1448
- celldetective/preprocessing.py +1620 -1220
- celldetective/processes/__init__.py +0 -0
- celldetective/processes/background_correction.py +271 -0
- celldetective/processes/compute_neighborhood.py +894 -0
- celldetective/processes/detect_events.py +246 -0
- celldetective/processes/measure_cells.py +565 -0
- celldetective/processes/segment_cells.py +760 -0
- celldetective/processes/track_cells.py +435 -0
- celldetective/processes/train_segmentation_model.py +694 -0
- celldetective/processes/train_signal_model.py +265 -0
- celldetective/processes/unified_process.py +292 -0
- celldetective/regionprops/_regionprops.py +358 -317
- celldetective/relative_measurements.py +987 -710
- celldetective/scripts/measure_cells.py +313 -212
- celldetective/scripts/measure_relative.py +90 -46
- celldetective/scripts/segment_cells.py +165 -104
- celldetective/scripts/segment_cells_thresholds.py +96 -68
- celldetective/scripts/track_cells.py +198 -149
- celldetective/scripts/train_segmentation_model.py +324 -201
- celldetective/scripts/train_signal_model.py +87 -45
- celldetective/segmentation.py +844 -749
- celldetective/signals.py +3514 -2861
- celldetective/tracking.py +1332 -1011
- celldetective/utils/__init__.py +0 -0
- celldetective/utils/cellpose_utils/__init__.py +133 -0
- celldetective/utils/color_mappings.py +42 -0
- celldetective/utils/data_cleaning.py +630 -0
- celldetective/utils/data_loaders.py +450 -0
- celldetective/utils/dataset_helpers.py +207 -0
- celldetective/utils/downloaders.py +197 -0
- celldetective/utils/event_detection/__init__.py +8 -0
- celldetective/utils/experiment.py +1782 -0
- celldetective/utils/image_augmenters.py +308 -0
- celldetective/utils/image_cleaning.py +74 -0
- celldetective/utils/image_loaders.py +926 -0
- celldetective/utils/image_transforms.py +335 -0
- celldetective/utils/io.py +62 -0
- celldetective/utils/mask_cleaning.py +348 -0
- celldetective/utils/mask_transforms.py +5 -0
- celldetective/utils/masks.py +184 -0
- celldetective/utils/maths.py +351 -0
- celldetective/utils/model_getters.py +325 -0
- celldetective/utils/model_loaders.py +296 -0
- celldetective/utils/normalization.py +380 -0
- celldetective/utils/parsing.py +465 -0
- celldetective/utils/plots/__init__.py +0 -0
- celldetective/utils/plots/regression.py +53 -0
- celldetective/utils/resources.py +34 -0
- celldetective/utils/stardist_utils/__init__.py +104 -0
- celldetective/utils/stats.py +90 -0
- celldetective/utils/types.py +21 -0
- {celldetective-1.4.1.post1.dist-info → celldetective-1.5.0b0.dist-info}/METADATA +1 -1
- celldetective-1.5.0b0.dist-info/RECORD +187 -0
- {celldetective-1.4.1.post1.dist-info → celldetective-1.5.0b0.dist-info}/WHEEL +1 -1
- tests/gui/test_new_project.py +129 -117
- tests/gui/test_project.py +127 -79
- tests/test_filters.py +39 -15
- tests/test_notebooks.py +8 -0
- tests/test_tracking.py +425 -144
- tests/test_utils.py +123 -77
- celldetective/gui/base_components.py +0 -23
- celldetective/gui/layouts.py +0 -1602
- celldetective/gui/processes/compute_neighborhood.py +0 -594
- celldetective/gui/processes/measure_cells.py +0 -360
- celldetective/gui/processes/segment_cells.py +0 -499
- celldetective/gui/processes/track_cells.py +0 -303
- celldetective/gui/processes/train_segmentation_model.py +0 -270
- celldetective/gui/processes/train_signal_model.py +0 -108
- celldetective/gui/table_ops/merge_groups.py +0 -118
- celldetective/gui/viewers.py +0 -1354
- celldetective/io.py +0 -3663
- celldetective/utils.py +0 -3108
- celldetective-1.4.1.post1.dist-info/RECORD +0 -123
- /celldetective/{gui/processes → processes}/downloader.py +0 -0
- {celldetective-1.4.1.post1.dist-info → celldetective-1.5.0b0.dist-info}/entry_points.txt +0 -0
- {celldetective-1.4.1.post1.dist-info → celldetective-1.5.0b0.dist-info}/licenses/LICENSE +0 -0
- {celldetective-1.4.1.post1.dist-info → celldetective-1.5.0b0.dist-info}/top_level.txt +0 -0
celldetective/filters.py
CHANGED
|
@@ -1,155 +1,250 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from celldetective.utils import interpolate_nan
|
|
4
|
-
import scipy.ndimage as snd
|
|
1
|
+
import numpy
|
|
2
|
+
|
|
3
|
+
from celldetective.utils.image_cleaning import interpolate_nan
|
|
5
4
|
import numpy as np
|
|
6
5
|
|
|
6
|
+
|
|
7
7
|
def gauss_filter(img, sigma, interpolate=True, *kwargs):
|
|
8
|
+
import scipy.ndimage as snd
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
if np.any(img != img) and interpolate:
|
|
11
|
+
img = interpolate_nan(img.astype(float))
|
|
12
|
+
|
|
13
|
+
return snd.gaussian_filter(img.astype(float), sigma, *kwargs)
|
|
11
14
|
|
|
12
|
-
return snd.gaussian_filter(img.astype(float), sigma, *kwargs)
|
|
13
15
|
|
|
14
16
|
def median_filter(img, size, interpolate=True, *kwargs):
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
if np.any(img != img) and interpolate:
|
|
19
|
+
img = interpolate_nan(img.astype(float))
|
|
20
|
+
|
|
21
|
+
size = int(size)
|
|
22
|
+
|
|
23
|
+
import scipy.ndimage as snd
|
|
24
|
+
|
|
25
|
+
return snd.median_filter(img, size, *kwargs)
|
|
18
26
|
|
|
19
|
-
size = int(size)
|
|
20
|
-
|
|
21
|
-
return snd.median_filter(img, size, *kwargs)
|
|
22
27
|
|
|
23
28
|
def maximum_filter(img, size, interpolate=True, *kwargs):
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
if np.any(img != img) and interpolate:
|
|
30
|
+
img = interpolate_nan(img.astype(float))
|
|
31
|
+
|
|
32
|
+
import scipy.ndimage as snd
|
|
33
|
+
|
|
34
|
+
return snd.maximum_filter(img.astype(float), size, *kwargs)
|
|
26
35
|
|
|
27
|
-
return snd.maximum_filter(img.astype(float), size, *kwargs)
|
|
28
36
|
|
|
29
37
|
def minimum_filter(img, size, interpolate=True, *kwargs):
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
if np.any(img != img) and interpolate:
|
|
39
|
+
img = interpolate_nan(img.astype(float))
|
|
40
|
+
|
|
41
|
+
import scipy.ndimage as snd
|
|
42
|
+
|
|
43
|
+
return snd.minimum_filter(img.astype(float), size, *kwargs)
|
|
32
44
|
|
|
33
|
-
return snd.minimum_filter(img.astype(float), size, *kwargs)
|
|
34
45
|
|
|
35
46
|
def percentile_filter(img, percentile, size, interpolate=True, *kwargs):
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
if np.any(img != img) and interpolate:
|
|
48
|
+
img = interpolate_nan(img.astype(float))
|
|
49
|
+
|
|
50
|
+
import scipy.ndimage as snd
|
|
51
|
+
|
|
52
|
+
return snd.percentile_filter(img.astype(float), percentile, size, *kwargs)
|
|
38
53
|
|
|
39
|
-
return snd.percentile_filter(img.astype(float), percentile, size, *kwargs)
|
|
40
54
|
|
|
41
55
|
def subtract_filter(img, value, *kwargs):
|
|
42
|
-
|
|
56
|
+
return img.astype(float) - value
|
|
57
|
+
|
|
43
58
|
|
|
44
59
|
def abs_filter(img, *kwargs):
|
|
45
|
-
|
|
60
|
+
return np.abs(img)
|
|
61
|
+
|
|
46
62
|
|
|
47
63
|
def ln_filter(img, interpolate=True, *kwargs):
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
if np.any(img != img) and interpolate:
|
|
65
|
+
img = interpolate_nan(img.astype(float))
|
|
50
66
|
|
|
51
|
-
|
|
52
|
-
|
|
67
|
+
img[np.where(img > 0.0)] = np.log(img[np.where(img > 0.0)])
|
|
68
|
+
img[np.where(img <= 0.0)] = 0.0
|
|
69
|
+
|
|
70
|
+
return img
|
|
53
71
|
|
|
54
|
-
return img
|
|
55
72
|
|
|
56
73
|
def variance_filter(img, size, interpolate=True):
|
|
57
74
|
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
if np.any(img != img) and interpolate:
|
|
76
|
+
img = interpolate_nan(img.astype(float))
|
|
77
|
+
|
|
78
|
+
size = int(size)
|
|
79
|
+
img = img.astype(float)
|
|
80
|
+
import scipy.ndimage as snd
|
|
60
81
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
win_mean = snd.uniform_filter(img, (size, size), mode="wrap")
|
|
83
|
+
win_sqr_mean = snd.uniform_filter(img**2, (size, size), mode="wrap")
|
|
84
|
+
img = win_sqr_mean - win_mean**2
|
|
85
|
+
|
|
86
|
+
return img
|
|
66
87
|
|
|
67
|
-
return img
|
|
68
88
|
|
|
69
89
|
def std_filter(img, size, interpolate=True):
|
|
70
90
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
if np.any(img != img) and interpolate:
|
|
92
|
+
img = interpolate_nan(img.astype(float))
|
|
93
|
+
|
|
94
|
+
size = int(size)
|
|
95
|
+
img = img.astype(float)
|
|
96
|
+
|
|
97
|
+
import scipy.ndimage as snd
|
|
98
|
+
|
|
99
|
+
win_mean = snd.uniform_filter(img, (size, size), mode="wrap")
|
|
100
|
+
win_sqr_mean = snd.uniform_filter(img**2, (size, size), mode="wrap")
|
|
101
|
+
win_sqr_mean[win_sqr_mean <= 0.0] = 0.0 # add this to prevent sqrt from breaking
|
|
102
|
+
|
|
103
|
+
sub = np.subtract(win_sqr_mean, win_mean**2)
|
|
104
|
+
sub[sub <= 0.0] = 0.0
|
|
105
|
+
img = np.sqrt(sub)
|
|
106
|
+
|
|
107
|
+
return img
|
|
108
|
+
|
|
86
109
|
|
|
87
110
|
def laplace_filter(img, output=float, interpolate=True, *kwargs):
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
if np.any(img != img) and interpolate:
|
|
112
|
+
img = interpolate_nan(img.astype(float))
|
|
113
|
+
import scipy.ndimage as snd
|
|
114
|
+
|
|
115
|
+
return snd.laplace(img.astype(float), *kwargs)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def dog_filter(
|
|
119
|
+
img, blob_size=None, sigma_low=1, sigma_high=2, interpolate=True, *kwargs
|
|
120
|
+
):
|
|
121
|
+
|
|
122
|
+
if np.any(img != img) and interpolate:
|
|
123
|
+
img = interpolate_nan(img.astype(float))
|
|
124
|
+
if blob_size is not None:
|
|
125
|
+
sigma_low = 1.0 / (1.0 + np.sqrt(2)) * blob_size
|
|
126
|
+
sigma_high = np.sqrt(2) * sigma_low
|
|
127
|
+
from skimage.filters import difference_of_gaussians
|
|
128
|
+
|
|
129
|
+
return difference_of_gaussians(img.astype(float), sigma_low, sigma_high, *kwargs)
|
|
130
|
+
|
|
100
131
|
|
|
101
132
|
def otsu_filter(img, *kwargs):
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
133
|
+
from skimage.filters import threshold_otsu
|
|
134
|
+
|
|
135
|
+
thresh = threshold_otsu(img.astype(float))
|
|
136
|
+
binary = img >= thresh
|
|
137
|
+
return binary.astype(float)
|
|
138
|
+
|
|
105
139
|
|
|
106
140
|
def multiotsu_filter(img, classes=3, *kwargs):
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
141
|
+
from skimage.filters import threshold_multiotsu
|
|
142
|
+
|
|
143
|
+
thresholds = threshold_multiotsu(img, classes=classes)
|
|
144
|
+
regions = np.digitize(img, bins=thresholds)
|
|
145
|
+
return regions.astype(float)
|
|
146
|
+
|
|
147
|
+
|
|
111
148
|
def local_filter(img, *kwargs):
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
149
|
+
from skimage.filters import threshold_local
|
|
150
|
+
|
|
151
|
+
thresh = threshold_local(img.astype(float), *kwargs)
|
|
152
|
+
binary = img >= thresh
|
|
153
|
+
return binary.astype(float)
|
|
154
|
+
|
|
115
155
|
|
|
116
156
|
def niblack_filter(img, *kwargs):
|
|
117
157
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
158
|
+
from skimage.filters import threshold_niblack
|
|
159
|
+
|
|
160
|
+
thresh = threshold_niblack(img, *kwargs)
|
|
161
|
+
binary = img >= thresh
|
|
162
|
+
return binary.astype(float)
|
|
163
|
+
|
|
121
164
|
|
|
122
165
|
def sauvola_filter(img, *kwargs):
|
|
123
166
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
167
|
+
from skimage.filters import threshold_sauvola
|
|
168
|
+
|
|
169
|
+
thresh = threshold_sauvola(img, *kwargs)
|
|
170
|
+
binary = img >= thresh
|
|
171
|
+
return binary.astype(float)
|
|
172
|
+
|
|
127
173
|
|
|
128
174
|
def log_filter(img, blob_size=None, sigma=1, interpolate=True, *kwargs):
|
|
129
175
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
176
|
+
if np.any(img != img) and interpolate:
|
|
177
|
+
img = interpolate_nan(img.astype(float))
|
|
178
|
+
if blob_size is not None:
|
|
179
|
+
sigma_low = 1.0 / (1.0 + np.sqrt(2)) * blob_size
|
|
180
|
+
sigma_high = np.sqrt(2) * sigma_low
|
|
181
|
+
|
|
182
|
+
import scipy.ndimage as snd
|
|
183
|
+
|
|
184
|
+
return snd.gaussian_laplace(img.astype(float), sigma, *kwargs)
|
|
135
185
|
|
|
136
|
-
return snd.gaussian_laplace(img.astype(float), sigma, *kwargs)
|
|
137
186
|
|
|
138
187
|
def tophat_filter(img, size, connectivity=4, interpolate=True, *kwargs):
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
188
|
+
|
|
189
|
+
if np.any(img != img) and interpolate:
|
|
190
|
+
img = interpolate_nan(img.astype(float))
|
|
191
|
+
import scipy.ndimage as snd
|
|
192
|
+
|
|
193
|
+
structure = snd.generate_binary_structure(rank=2, connectivity=connectivity)
|
|
194
|
+
img = snd.white_tophat(img.astype(float), structure=structure, size=size, *kwargs)
|
|
195
|
+
return img
|
|
196
|
+
|
|
145
197
|
|
|
146
198
|
def invert_filter(img, value=65535, *kwargs):
|
|
147
|
-
|
|
148
|
-
img = img.astype(float)
|
|
149
199
|
|
|
150
|
-
|
|
151
|
-
|
|
200
|
+
img = img.astype(float)
|
|
201
|
+
|
|
202
|
+
image_fill = np.zeros_like(img)
|
|
203
|
+
image_fill[:, :] = value
|
|
204
|
+
|
|
205
|
+
inverted = np.subtract(image_fill, img, where=img == img)
|
|
206
|
+
return inverted
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def filter_image(img, filters=None):
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
Apply one or more image filters to the input image.
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
img : ndarray
|
|
217
|
+
The input image to be filtered.
|
|
218
|
+
filters : list or None, optional
|
|
219
|
+
A list of filters to be applied to the image. Each filter is represented as a tuple or list with the first element being
|
|
220
|
+
the filter function name (minus the '_filter' extension, as listed in software.filters) and the subsequent elements being
|
|
221
|
+
the arguments for that filter function. If None, the original image is returned without any filtering applied. Default is None.
|
|
222
|
+
|
|
223
|
+
Returns
|
|
224
|
+
-------
|
|
225
|
+
ndarray
|
|
226
|
+
The filtered image.
|
|
227
|
+
|
|
228
|
+
Notes
|
|
229
|
+
-----
|
|
230
|
+
This function applies a series of image filters to the input image. The filters are specified as a list of tuples,
|
|
231
|
+
where each tuple contains the name of the filter function and its corresponding arguments. The filters are applied
|
|
232
|
+
sequentially to the image. If no filters are provided, the original image is returned unchanged.
|
|
233
|
+
|
|
234
|
+
Examples
|
|
235
|
+
--------
|
|
236
|
+
>>> image = np.random.rand(256, 256)
|
|
237
|
+
>>> filtered_image = filter_image(image, filters=[('gaussian', 3), ('median', 5)])
|
|
238
|
+
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
if filters is None:
|
|
242
|
+
return img
|
|
152
243
|
|
|
153
|
-
|
|
154
|
-
|
|
244
|
+
if img.ndim == 3:
|
|
245
|
+
img = np.squeeze(img)
|
|
155
246
|
|
|
247
|
+
for f in filters:
|
|
248
|
+
func = eval(f[0] + "_filter")
|
|
249
|
+
img = func(img, *f[1:])
|
|
250
|
+
return img
|