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.
Files changed (151) 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 +304 -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/measure_cells.py +565 -0
  81. celldetective/processes/segment_cells.py +760 -0
  82. celldetective/processes/track_cells.py +435 -0
  83. celldetective/processes/train_segmentation_model.py +694 -0
  84. celldetective/processes/train_signal_model.py +265 -0
  85. celldetective/processes/unified_process.py +292 -0
  86. celldetective/regionprops/_regionprops.py +358 -317
  87. celldetective/relative_measurements.py +987 -710
  88. celldetective/scripts/measure_cells.py +313 -212
  89. celldetective/scripts/measure_relative.py +90 -46
  90. celldetective/scripts/segment_cells.py +165 -104
  91. celldetective/scripts/segment_cells_thresholds.py +96 -68
  92. celldetective/scripts/track_cells.py +198 -149
  93. celldetective/scripts/train_segmentation_model.py +324 -201
  94. celldetective/scripts/train_signal_model.py +87 -45
  95. celldetective/segmentation.py +844 -749
  96. celldetective/signals.py +3514 -2861
  97. celldetective/tracking.py +30 -15
  98. celldetective/utils/__init__.py +0 -0
  99. celldetective/utils/cellpose_utils/__init__.py +133 -0
  100. celldetective/utils/color_mappings.py +42 -0
  101. celldetective/utils/data_cleaning.py +630 -0
  102. celldetective/utils/data_loaders.py +450 -0
  103. celldetective/utils/dataset_helpers.py +207 -0
  104. celldetective/utils/downloaders.py +197 -0
  105. celldetective/utils/event_detection/__init__.py +8 -0
  106. celldetective/utils/experiment.py +1782 -0
  107. celldetective/utils/image_augmenters.py +308 -0
  108. celldetective/utils/image_cleaning.py +74 -0
  109. celldetective/utils/image_loaders.py +926 -0
  110. celldetective/utils/image_transforms.py +335 -0
  111. celldetective/utils/io.py +62 -0
  112. celldetective/utils/mask_cleaning.py +348 -0
  113. celldetective/utils/mask_transforms.py +5 -0
  114. celldetective/utils/masks.py +184 -0
  115. celldetective/utils/maths.py +351 -0
  116. celldetective/utils/model_getters.py +325 -0
  117. celldetective/utils/model_loaders.py +296 -0
  118. celldetective/utils/normalization.py +380 -0
  119. celldetective/utils/parsing.py +465 -0
  120. celldetective/utils/plots/__init__.py +0 -0
  121. celldetective/utils/plots/regression.py +53 -0
  122. celldetective/utils/resources.py +34 -0
  123. celldetective/utils/stardist_utils/__init__.py +104 -0
  124. celldetective/utils/stats.py +90 -0
  125. celldetective/utils/types.py +21 -0
  126. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/METADATA +1 -1
  127. celldetective-1.5.0b0.dist-info/RECORD +187 -0
  128. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/WHEEL +1 -1
  129. tests/gui/test_new_project.py +129 -117
  130. tests/gui/test_project.py +127 -79
  131. tests/test_filters.py +39 -15
  132. tests/test_notebooks.py +8 -0
  133. tests/test_tracking.py +232 -13
  134. tests/test_utils.py +123 -77
  135. celldetective/gui/base_components.py +0 -23
  136. celldetective/gui/layouts.py +0 -1602
  137. celldetective/gui/processes/compute_neighborhood.py +0 -594
  138. celldetective/gui/processes/measure_cells.py +0 -360
  139. celldetective/gui/processes/segment_cells.py +0 -499
  140. celldetective/gui/processes/track_cells.py +0 -303
  141. celldetective/gui/processes/train_segmentation_model.py +0 -270
  142. celldetective/gui/processes/train_signal_model.py +0 -108
  143. celldetective/gui/table_ops/merge_groups.py +0 -118
  144. celldetective/gui/viewers.py +0 -1354
  145. celldetective/io.py +0 -3663
  146. celldetective/utils.py +0 -3108
  147. celldetective-1.4.2.dist-info/RECORD +0 -123
  148. /celldetective/{gui/processes → processes}/downloader.py +0 -0
  149. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/entry_points.txt +0 -0
  150. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/licenses/LICENSE +0 -0
  151. {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 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)