celldetective 1.4.2__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 +6 -22
- 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 -1701
- 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 +30 -15
- 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.2.dist-info → celldetective-1.5.0b0.dist-info}/METADATA +1 -1
- celldetective-1.5.0b0.dist-info/RECORD +187 -0
- {celldetective-1.4.2.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 +232 -13
- 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.2.dist-info/RECORD +0 -123
- /celldetective/{gui/processes → processes}/downloader.py +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/entry_points.txt +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/licenses/LICENSE +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/top_level.txt +0 -0
tests/test_utils.py
CHANGED
|
@@ -2,117 +2,163 @@ import unittest
|
|
|
2
2
|
import matplotlib.pyplot as plt
|
|
3
3
|
import numpy as np
|
|
4
4
|
import os
|
|
5
|
-
from celldetective.utils import
|
|
5
|
+
from celldetective.utils.dataset_helpers import split_by_ratio
|
|
6
|
+
from celldetective.utils.masks import create_patch_mask
|
|
7
|
+
from celldetective.utils.image_transforms import (
|
|
8
|
+
estimate_unreliable_edge,
|
|
9
|
+
unpad,
|
|
10
|
+
mask_edges,
|
|
11
|
+
)
|
|
12
|
+
from celldetective.utils.image_loaders import (
|
|
13
|
+
_get_img_num_per_channel,
|
|
14
|
+
_extract_channel_indices,
|
|
15
|
+
)
|
|
16
|
+
from celldetective.utils.data_cleaning import remove_redundant_features
|
|
17
|
+
from celldetective.utils.experiment import extract_experiment_channels
|
|
18
|
+
|
|
6
19
|
|
|
7
20
|
class TestPatchMask(unittest.TestCase):
|
|
8
21
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
22
|
+
@classmethod
|
|
23
|
+
def setUpClass(self):
|
|
24
|
+
self.radius = 3
|
|
25
|
+
|
|
26
|
+
def test_correct_shape(self):
|
|
27
|
+
self.patch = create_patch_mask(self.radius, self.radius)
|
|
28
|
+
self.assertEqual(self.patch.shape, (3, 3))
|
|
12
29
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
30
|
+
def test_correct_ring(self):
|
|
31
|
+
self.patch = create_patch_mask(5, 5, radius=[1, 2])
|
|
32
|
+
self.assertFalse(self.patch[2, 2])
|
|
16
33
|
|
|
17
|
-
def test_correct_ring(self):
|
|
18
|
-
self.patch = create_patch_mask(5, 5,radius=[1,2])
|
|
19
|
-
self.assertFalse(self.patch[2,2])
|
|
20
34
|
|
|
21
35
|
class TestRemoveRedundantFeatures(unittest.TestCase):
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
@classmethod
|
|
38
|
+
def setUpClass(self):
|
|
39
|
+
self.list_a = ["feat1", "feat2", "feat3", "feat4", "intensity_mean"]
|
|
40
|
+
self.list_b = ["feat5", "feat2", "feat1", "feat6", "test_channel_mean"]
|
|
41
|
+
self.expected = ["feat3", "feat4"]
|
|
28
42
|
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
def test_remove_red_features(self):
|
|
44
|
+
self.assertEqual(
|
|
45
|
+
remove_redundant_features(
|
|
46
|
+
self.list_a, self.list_b, channel_names=["test_channel"]
|
|
47
|
+
),
|
|
48
|
+
self.expected,
|
|
49
|
+
)
|
|
31
50
|
|
|
32
51
|
|
|
33
52
|
class TestExtractChannelIndices(unittest.TestCase):
|
|
34
53
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
54
|
+
@classmethod
|
|
55
|
+
def setUpClass(self):
|
|
56
|
+
self.channels = ["ch1", "ch2", "ch3", "ch4"]
|
|
57
|
+
self.required_channels = ["ch4", "ch2"]
|
|
58
|
+
self.expected_indices = [3, 1]
|
|
40
59
|
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
def test_extracted_channels_are_correct(self):
|
|
61
|
+
self.assertEqual(
|
|
62
|
+
list(_extract_channel_indices(self.channels, self.required_channels)),
|
|
63
|
+
self.expected_indices,
|
|
64
|
+
)
|
|
43
65
|
|
|
44
66
|
|
|
45
67
|
class TestImgIndexPerChannel(unittest.TestCase):
|
|
46
68
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
69
|
+
@classmethod
|
|
70
|
+
def setUpClass(self):
|
|
71
|
+
self.channels_indices = [1]
|
|
72
|
+
self.len_movie = 5
|
|
73
|
+
self.nbr_channels = 3
|
|
74
|
+
self.expected_indices = [1, 4, 7, 10, 13]
|
|
53
75
|
|
|
54
|
-
|
|
55
|
-
|
|
76
|
+
def test_index_sequence_is_correct(self):
|
|
77
|
+
self.assertEqual(
|
|
78
|
+
list(
|
|
79
|
+
_get_img_num_per_channel(
|
|
80
|
+
self.channels_indices, self.len_movie, self.nbr_channels
|
|
81
|
+
)[0]
|
|
82
|
+
),
|
|
83
|
+
self.expected_indices,
|
|
84
|
+
)
|
|
56
85
|
|
|
57
86
|
|
|
58
87
|
class TestSplitArrayByRatio(unittest.TestCase):
|
|
59
88
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
@classmethod
|
|
90
|
+
def setUpClass(self):
|
|
91
|
+
self.array_length = 100
|
|
92
|
+
self.array = np.ones(self.array_length)
|
|
93
|
+
|
|
94
|
+
def test_ratio_split_is_correct(self):
|
|
95
|
+
split_array = split_by_ratio(self.array, 0.5, 0.25, 0.1)
|
|
96
|
+
self.assertTrue(
|
|
97
|
+
np.all(
|
|
98
|
+
[
|
|
99
|
+
len(split_array[0]) == 50,
|
|
100
|
+
len(split_array[1]) == 25,
|
|
101
|
+
len(split_array[2]) == 10,
|
|
102
|
+
]
|
|
103
|
+
)
|
|
104
|
+
)
|
|
64
105
|
|
|
65
|
-
def test_ratio_split_is_correct(self):
|
|
66
|
-
split_array = split_by_ratio(self.array,0.5,0.25,0.1)
|
|
67
|
-
self.assertTrue(np.all([len(split_array[0])==50, len(split_array[1])==25, len(split_array[2])==10]))
|
|
68
106
|
|
|
69
107
|
class TestUnpad(unittest.TestCase):
|
|
70
108
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
109
|
+
@classmethod
|
|
110
|
+
def setUpClass(self):
|
|
111
|
+
self.array = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]])
|
|
112
|
+
|
|
113
|
+
def test_unpad(self):
|
|
114
|
+
expected_unpad_array = np.array([[1]])
|
|
115
|
+
test_array = unpad(self.array, 1)
|
|
116
|
+
self.assertTrue(np.array_equal(test_array, expected_unpad_array))
|
|
76
117
|
|
|
77
|
-
def test_unpad(self):
|
|
78
|
-
expected_unpad_array = np.array([[1]])
|
|
79
|
-
test_array = unpad(self.array, 1)
|
|
80
|
-
self.assertTrue(np.array_equal(test_array, expected_unpad_array))
|
|
81
118
|
|
|
82
119
|
class TestMaskEdge(unittest.TestCase):
|
|
83
120
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
121
|
+
@classmethod
|
|
122
|
+
def setUpClass(self):
|
|
123
|
+
self.binary_mask = np.array(
|
|
124
|
+
[
|
|
125
|
+
[1, 1, 1, 1, 1],
|
|
126
|
+
[1, 1, 1, 1, 1],
|
|
127
|
+
[1, 1, 1, 1, 1],
|
|
128
|
+
[1, 1, 1, 1, 1],
|
|
129
|
+
[1, 1, 1, 1, 1],
|
|
130
|
+
]
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def test_mask_edge_properly(self):
|
|
134
|
+
expected_output = np.array(
|
|
135
|
+
[
|
|
136
|
+
[False, False, False, False, False],
|
|
137
|
+
[False, True, True, True, False],
|
|
138
|
+
[False, True, True, True, False],
|
|
139
|
+
[False, True, True, True, False],
|
|
140
|
+
[False, False, False, False, False],
|
|
141
|
+
]
|
|
142
|
+
)
|
|
143
|
+
actual_output = mask_edges(self.binary_mask, 1)
|
|
144
|
+
self.assertTrue(np.array_equal(actual_output, expected_output))
|
|
145
|
+
|
|
100
146
|
|
|
101
147
|
class TestEstimateFilterEdge(unittest.TestCase):
|
|
102
148
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
149
|
+
@classmethod
|
|
150
|
+
def setUpClass(self):
|
|
151
|
+
self.protocol1 = [["gauss", 2], ["std", 4]]
|
|
152
|
+
self.expected1 = 6
|
|
153
|
+
self.protocol2 = [["gauss", 4], ["variance", "string_arg"]]
|
|
154
|
+
self.expected2 = 4
|
|
155
|
+
|
|
156
|
+
def test_edge_is_estimated_properly_with_only_number_arguments(self):
|
|
157
|
+
self.assertEqual(self.expected1, estimate_unreliable_edge(self.protocol1))
|
|
109
158
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def test_edge_is_estimated_properly_with_mixed_arguments(self):
|
|
114
|
-
self.assertEqual(self.expected2, estimate_unreliable_edge(self.protocol2))
|
|
159
|
+
def test_edge_is_estimated_properly_with_mixed_arguments(self):
|
|
160
|
+
self.assertEqual(self.expected2, estimate_unreliable_edge(self.protocol2))
|
|
115
161
|
|
|
116
162
|
|
|
117
|
-
if __name__=="__main__":
|
|
118
|
-
|
|
163
|
+
if __name__ == "__main__":
|
|
164
|
+
unittest.main()
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from PyQt5.QtWidgets import QMainWindow, QWidget, QDialog
|
|
2
|
-
from PyQt5.QtCore import Qt
|
|
3
|
-
from celldetective.gui import Styles
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class CelldetectiveWidget(QWidget, Styles):
|
|
7
|
-
def __init__(self, *args, **kwargs):
|
|
8
|
-
super().__init__(*args, **kwargs)
|
|
9
|
-
self.setWindowIcon(self.celldetective_icon)
|
|
10
|
-
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class CelldetectiveMainWindow(QMainWindow, Styles):
|
|
14
|
-
def __init__(self, *args, **kwargs):
|
|
15
|
-
super().__init__(*args, **kwargs)
|
|
16
|
-
self.setWindowIcon(self.celldetective_icon)
|
|
17
|
-
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class CelldetectiveDialog(QDialog, Styles):
|
|
21
|
-
def __init__(self, *args, **kwargs):
|
|
22
|
-
super().__init__(*args, **kwargs)
|
|
23
|
-
self.setWindowIcon(self.celldetective_icon)
|