celldetective 1.4.2__py3-none-any.whl → 1.5.0b1__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 (152) hide show
  1. celldetective/__init__.py +25 -0
  2. celldetective/__main__.py +62 -43
  3. celldetective/_version.py +1 -1
  4. celldetective/extra_properties.py +477 -399
  5. celldetective/filters.py +192 -97
  6. celldetective/gui/InitWindow.py +541 -411
  7. celldetective/gui/__init__.py +0 -15
  8. celldetective/gui/about.py +44 -39
  9. celldetective/gui/analyze_block.py +120 -84
  10. celldetective/gui/base/__init__.py +0 -0
  11. celldetective/gui/base/channel_norm_generator.py +335 -0
  12. celldetective/gui/base/components.py +249 -0
  13. celldetective/gui/base/feature_choice.py +92 -0
  14. celldetective/gui/base/figure_canvas.py +52 -0
  15. celldetective/gui/base/list_widget.py +133 -0
  16. celldetective/gui/{styles.py → base/styles.py} +92 -36
  17. celldetective/gui/base/utils.py +33 -0
  18. celldetective/gui/base_annotator.py +900 -767
  19. celldetective/gui/classifier_widget.py +6 -22
  20. celldetective/gui/configure_new_exp.py +777 -671
  21. celldetective/gui/control_panel.py +635 -524
  22. celldetective/gui/dynamic_progress.py +449 -0
  23. celldetective/gui/event_annotator.py +2023 -1662
  24. celldetective/gui/generic_signal_plot.py +1292 -944
  25. celldetective/gui/gui_utils.py +899 -1289
  26. celldetective/gui/interactions_block.py +658 -0
  27. celldetective/gui/interactive_timeseries_viewer.py +447 -0
  28. celldetective/gui/json_readers.py +48 -15
  29. celldetective/gui/layouts/__init__.py +5 -0
  30. celldetective/gui/layouts/background_model_free_layout.py +537 -0
  31. celldetective/gui/layouts/channel_offset_layout.py +134 -0
  32. celldetective/gui/layouts/local_correction_layout.py +91 -0
  33. celldetective/gui/layouts/model_fit_layout.py +372 -0
  34. celldetective/gui/layouts/operation_layout.py +68 -0
  35. celldetective/gui/layouts/protocol_designer_layout.py +96 -0
  36. celldetective/gui/pair_event_annotator.py +3130 -2435
  37. celldetective/gui/plot_measurements.py +586 -267
  38. celldetective/gui/plot_signals_ui.py +724 -506
  39. celldetective/gui/preprocessing_block.py +395 -0
  40. celldetective/gui/process_block.py +1678 -1831
  41. celldetective/gui/seg_model_loader.py +580 -473
  42. celldetective/gui/settings/__init__.py +0 -7
  43. celldetective/gui/settings/_cellpose_model_params.py +181 -0
  44. celldetective/gui/settings/_event_detection_model_params.py +95 -0
  45. celldetective/gui/settings/_segmentation_model_params.py +159 -0
  46. celldetective/gui/settings/_settings_base.py +77 -65
  47. celldetective/gui/settings/_settings_event_model_training.py +752 -526
  48. celldetective/gui/settings/_settings_measurements.py +1133 -964
  49. celldetective/gui/settings/_settings_neighborhood.py +574 -488
  50. celldetective/gui/settings/_settings_segmentation_model_training.py +779 -564
  51. celldetective/gui/settings/_settings_signal_annotator.py +329 -305
  52. celldetective/gui/settings/_settings_tracking.py +1304 -1094
  53. celldetective/gui/settings/_stardist_model_params.py +98 -0
  54. celldetective/gui/survival_ui.py +422 -312
  55. celldetective/gui/tableUI.py +1665 -1701
  56. celldetective/gui/table_ops/_maths.py +295 -0
  57. celldetective/gui/table_ops/_merge_groups.py +140 -0
  58. celldetective/gui/table_ops/_merge_one_hot.py +95 -0
  59. celldetective/gui/table_ops/_query_table.py +43 -0
  60. celldetective/gui/table_ops/_rename_col.py +44 -0
  61. celldetective/gui/thresholds_gui.py +382 -179
  62. celldetective/gui/viewers/__init__.py +0 -0
  63. celldetective/gui/viewers/base_viewer.py +700 -0
  64. celldetective/gui/viewers/channel_offset_viewer.py +331 -0
  65. celldetective/gui/viewers/contour_viewer.py +394 -0
  66. celldetective/gui/viewers/size_viewer.py +153 -0
  67. celldetective/gui/viewers/spot_detection_viewer.py +341 -0
  68. celldetective/gui/viewers/threshold_viewer.py +309 -0
  69. celldetective/gui/workers.py +403 -126
  70. celldetective/log_manager.py +92 -0
  71. celldetective/measure.py +1895 -1478
  72. celldetective/napari/__init__.py +0 -0
  73. celldetective/napari/utils.py +1025 -0
  74. celldetective/neighborhood.py +1914 -1448
  75. celldetective/preprocessing.py +1620 -1220
  76. celldetective/processes/__init__.py +0 -0
  77. celldetective/processes/background_correction.py +271 -0
  78. celldetective/processes/compute_neighborhood.py +894 -0
  79. celldetective/processes/detect_events.py +246 -0
  80. celldetective/processes/downloader.py +137 -0
  81. celldetective/processes/measure_cells.py +565 -0
  82. celldetective/processes/segment_cells.py +760 -0
  83. celldetective/processes/track_cells.py +435 -0
  84. celldetective/processes/train_segmentation_model.py +694 -0
  85. celldetective/processes/train_signal_model.py +265 -0
  86. celldetective/processes/unified_process.py +292 -0
  87. celldetective/regionprops/_regionprops.py +358 -317
  88. celldetective/relative_measurements.py +987 -710
  89. celldetective/scripts/measure_cells.py +313 -212
  90. celldetective/scripts/measure_relative.py +90 -46
  91. celldetective/scripts/segment_cells.py +165 -104
  92. celldetective/scripts/segment_cells_thresholds.py +96 -68
  93. celldetective/scripts/track_cells.py +198 -149
  94. celldetective/scripts/train_segmentation_model.py +324 -201
  95. celldetective/scripts/train_signal_model.py +87 -45
  96. celldetective/segmentation.py +844 -749
  97. celldetective/signals.py +3514 -2861
  98. celldetective/tracking.py +30 -15
  99. celldetective/utils/__init__.py +0 -0
  100. celldetective/utils/cellpose_utils/__init__.py +133 -0
  101. celldetective/utils/color_mappings.py +42 -0
  102. celldetective/utils/data_cleaning.py +630 -0
  103. celldetective/utils/data_loaders.py +450 -0
  104. celldetective/utils/dataset_helpers.py +207 -0
  105. celldetective/utils/downloaders.py +235 -0
  106. celldetective/utils/event_detection/__init__.py +8 -0
  107. celldetective/utils/experiment.py +1782 -0
  108. celldetective/utils/image_augmenters.py +308 -0
  109. celldetective/utils/image_cleaning.py +74 -0
  110. celldetective/utils/image_loaders.py +926 -0
  111. celldetective/utils/image_transforms.py +335 -0
  112. celldetective/utils/io.py +62 -0
  113. celldetective/utils/mask_cleaning.py +348 -0
  114. celldetective/utils/mask_transforms.py +5 -0
  115. celldetective/utils/masks.py +184 -0
  116. celldetective/utils/maths.py +351 -0
  117. celldetective/utils/model_getters.py +325 -0
  118. celldetective/utils/model_loaders.py +296 -0
  119. celldetective/utils/normalization.py +380 -0
  120. celldetective/utils/parsing.py +465 -0
  121. celldetective/utils/plots/__init__.py +0 -0
  122. celldetective/utils/plots/regression.py +53 -0
  123. celldetective/utils/resources.py +34 -0
  124. celldetective/utils/stardist_utils/__init__.py +104 -0
  125. celldetective/utils/stats.py +90 -0
  126. celldetective/utils/types.py +21 -0
  127. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/METADATA +1 -1
  128. celldetective-1.5.0b1.dist-info/RECORD +187 -0
  129. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/WHEEL +1 -1
  130. tests/gui/test_new_project.py +129 -117
  131. tests/gui/test_project.py +127 -79
  132. tests/test_filters.py +39 -15
  133. tests/test_notebooks.py +8 -0
  134. tests/test_tracking.py +232 -13
  135. tests/test_utils.py +123 -77
  136. celldetective/gui/base_components.py +0 -23
  137. celldetective/gui/layouts.py +0 -1602
  138. celldetective/gui/processes/compute_neighborhood.py +0 -594
  139. celldetective/gui/processes/downloader.py +0 -111
  140. celldetective/gui/processes/measure_cells.py +0 -360
  141. celldetective/gui/processes/segment_cells.py +0 -499
  142. celldetective/gui/processes/track_cells.py +0 -303
  143. celldetective/gui/processes/train_segmentation_model.py +0 -270
  144. celldetective/gui/processes/train_signal_model.py +0 -108
  145. celldetective/gui/table_ops/merge_groups.py +0 -118
  146. celldetective/gui/viewers.py +0 -1354
  147. celldetective/io.py +0 -3663
  148. celldetective/utils.py +0 -3108
  149. celldetective-1.4.2.dist-info/RECORD +0 -123
  150. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/entry_points.txt +0 -0
  151. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.dist-info}/licenses/LICENSE +0 -0
  152. {celldetective-1.4.2.dist-info → celldetective-1.5.0b1.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 create_patch_mask, remove_redundant_features, _extract_channel_indices, _get_img_num_per_channel, split_by_ratio,extract_experiment_channels, estimate_unreliable_edge, unpad, mask_edges
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
- @classmethod
10
- def setUpClass(self):
11
- self.radius = 3
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
- def test_correct_shape(self):
14
- self.patch = create_patch_mask(self.radius, self.radius)
15
- self.assertEqual(self.patch.shape,(3,3))
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
- @classmethod
24
- def setUpClass(self):
25
- self.list_a = ['feat1','feat2','feat3','feat4','intensity_mean']
26
- self.list_b = ['feat5','feat2','feat1','feat6','test_channel_mean']
27
- self.expected = ['feat3','feat4']
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
- def test_remove_red_features(self):
30
- self.assertEqual(remove_redundant_features(self.list_a, self.list_b, channel_names=['test_channel']), self.expected)
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
- @classmethod
36
- def setUpClass(self):
37
- self.channels = ['ch1','ch2','ch3','ch4']
38
- self.required_channels = ['ch4','ch2']
39
- self.expected_indices = [3,1]
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
- def test_extracted_channels_are_correct(self):
42
- self.assertEqual(list(_extract_channel_indices(self.channels, self.required_channels)), self.expected_indices)
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
- @classmethod
48
- def setUpClass(self):
49
- self.channels_indices = [1]
50
- self.len_movie = 5
51
- self.nbr_channels = 3
52
- self.expected_indices = [1,4,7,10,13]
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
- def test_index_sequence_is_correct(self):
55
- self.assertEqual(list(_get_img_num_per_channel(self.channels_indices, self.len_movie, self.nbr_channels)[0]), self.expected_indices)
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
- @classmethod
61
- def setUpClass(self):
62
- self.array_length = 100
63
- self.array = np.ones(self.array_length)
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
- @classmethod
72
- def setUpClass(self):
73
- self.array = np.array([[0,0,0],
74
- [0,1,0],
75
- [0,0,0]])
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
- @classmethod
85
- def setUpClass(self):
86
- self.binary_mask = np.array([[1, 1, 1, 1, 1],
87
- [1, 1, 1, 1, 1],
88
- [1, 1, 1, 1, 1],
89
- [1, 1, 1, 1, 1],
90
- [1, 1, 1, 1, 1]])
91
-
92
- def test_mask_edge_properly(self):
93
- expected_output = np.array([[False, False, False, False, False],
94
- [False, True, True, True, False],
95
- [False, True, True, True, False],
96
- [False, True, True, True, False],
97
- [False, False, False, False, False]])
98
- actual_output = mask_edges(self.binary_mask, 1)
99
- self.assertTrue(np.array_equal(actual_output, expected_output))
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
- @classmethod
104
- def setUpClass(self):
105
- self.protocol1 = [['gauss',2],['std',4]]
106
- self.expected1 = 6
107
- self.protocol2 = [['gauss',4],['variance','string_arg']]
108
- self.expected2 = 4
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
- def test_edge_is_estimated_properly_with_only_number_arguments(self):
111
- self.assertEqual(self.expected1, estimate_unreliable_edge(self.protocol1))
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
- unittest.main()
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)