celldetective 1.0.2__py3-none-any.whl → 1.1.0__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 (56) hide show
  1. celldetective/__main__.py +2 -2
  2. celldetective/events.py +2 -44
  3. celldetective/filters.py +4 -5
  4. celldetective/gui/__init__.py +1 -1
  5. celldetective/gui/analyze_block.py +37 -10
  6. celldetective/gui/btrack_options.py +24 -23
  7. celldetective/gui/classifier_widget.py +62 -19
  8. celldetective/gui/configure_new_exp.py +32 -35
  9. celldetective/gui/control_panel.py +115 -81
  10. celldetective/gui/gui_utils.py +674 -396
  11. celldetective/gui/json_readers.py +7 -6
  12. celldetective/gui/layouts.py +755 -0
  13. celldetective/gui/measurement_options.py +168 -487
  14. celldetective/gui/neighborhood_options.py +322 -270
  15. celldetective/gui/plot_measurements.py +1114 -0
  16. celldetective/gui/plot_signals_ui.py +20 -20
  17. celldetective/gui/process_block.py +449 -169
  18. celldetective/gui/retrain_segmentation_model_options.py +27 -26
  19. celldetective/gui/retrain_signal_model_options.py +25 -24
  20. celldetective/gui/seg_model_loader.py +31 -27
  21. celldetective/gui/signal_annotator.py +2326 -2295
  22. celldetective/gui/signal_annotator_options.py +18 -16
  23. celldetective/gui/styles.py +16 -1
  24. celldetective/gui/survival_ui.py +61 -39
  25. celldetective/gui/tableUI.py +60 -23
  26. celldetective/gui/thresholds_gui.py +68 -66
  27. celldetective/gui/viewers.py +596 -0
  28. celldetective/io.py +234 -23
  29. celldetective/measure.py +37 -32
  30. celldetective/neighborhood.py +495 -27
  31. celldetective/preprocessing.py +683 -0
  32. celldetective/scripts/analyze_signals.py +7 -0
  33. celldetective/scripts/measure_cells.py +12 -0
  34. celldetective/scripts/segment_cells.py +5 -0
  35. celldetective/scripts/track_cells.py +11 -0
  36. celldetective/signals.py +221 -98
  37. celldetective/tracking.py +0 -1
  38. celldetective/utils.py +178 -36
  39. celldetective-1.1.0.dist-info/METADATA +305 -0
  40. celldetective-1.1.0.dist-info/RECORD +80 -0
  41. {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/top_level.txt +1 -0
  42. tests/__init__.py +0 -0
  43. tests/test_events.py +28 -0
  44. tests/test_filters.py +24 -0
  45. tests/test_io.py +70 -0
  46. tests/test_measure.py +141 -0
  47. tests/test_neighborhood.py +70 -0
  48. tests/test_segmentation.py +93 -0
  49. tests/test_signals.py +135 -0
  50. tests/test_tracking.py +164 -0
  51. tests/test_utils.py +71 -0
  52. celldetective-1.0.2.dist-info/METADATA +0 -192
  53. celldetective-1.0.2.dist-info/RECORD +0 -66
  54. {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/LICENSE +0 -0
  55. {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/WHEEL +0 -0
  56. {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/entry_points.txt +0 -0
tests/test_tracking.py ADDED
@@ -0,0 +1,164 @@
1
+ import unittest
2
+ import numpy as np
3
+ import pandas as pd
4
+ from celldetective.tracking import filter_by_endpoints, extrapolate_tracks, filter_by_tracklength, interpolate_time_gaps
5
+
6
+ class TestTrackFilteringByEndpoint(unittest.TestCase):
7
+
8
+ @classmethod
9
+ def setUpClass(self):
10
+ self.tracks = pd.DataFrame([{"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
11
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
12
+ {"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 30, "POSITION_Y": 5},
13
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 40, "POSITION_Y": 0},
14
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
15
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
16
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
17
+ {"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 10, "POSITION_Y": 25}
18
+
19
+ ])
20
+
21
+ def test_filter_not_in_last(self):
22
+ self.filtered_tracks = filter_by_endpoints(self.tracks, remove_not_in_first=False, remove_not_in_last=True)
23
+ track_ids = list(self.filtered_tracks['TRACK_ID'].unique())
24
+ self.assertEqual(track_ids,[0.])
25
+
26
+ def test_filter_not_in_first(self):
27
+ self.filtered_tracks = filter_by_endpoints(self.tracks, remove_not_in_first=True, remove_not_in_last=False)
28
+ track_ids = list(self.filtered_tracks['TRACK_ID'].unique())
29
+ self.assertEqual(track_ids,[0.,2.])
30
+
31
+ def test_no_filter_does_nothing(self):
32
+ self.filtered_tracks = filter_by_endpoints(self.tracks, remove_not_in_first=False, remove_not_in_last=False)
33
+ track_ids = list(self.filtered_tracks['TRACK_ID'].unique())
34
+ self.assertEqual(track_ids,list(self.tracks['TRACK_ID'].unique()))
35
+
36
+
37
+ class TestTrackFilteringByLength(unittest.TestCase):
38
+
39
+ @classmethod
40
+ def setUpClass(self):
41
+ self.tracks = pd.DataFrame([{"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
42
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
43
+ {"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 30, "POSITION_Y": 5},
44
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 40, "POSITION_Y": 0},
45
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
46
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
47
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
48
+ {"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 10, "POSITION_Y": 25}
49
+ ])
50
+
51
+ def test_filter_by_tracklength_of_zero(self):
52
+ self.filtered_tracks = filter_by_tracklength(self.tracks, minimum_tracklength=0)
53
+ track_ids = list(self.filtered_tracks['TRACK_ID'].unique())
54
+ self.assertEqual(track_ids,[0.,1.,2.])
55
+
56
+ def test_filter_by_tracklength_of_three(self):
57
+ self.filtered_tracks = filter_by_tracklength(self.tracks, minimum_tracklength=3)
58
+ track_ids = list(self.filtered_tracks['TRACK_ID'].unique())
59
+ self.assertEqual(track_ids,[0.])
60
+
61
+
62
+ class TestTrackInterpolation(unittest.TestCase):
63
+
64
+ @classmethod
65
+ def setUpClass(self):
66
+
67
+ self.tracks = pd.DataFrame([{"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
68
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
69
+ #{"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 20, "POSITION_Y": 5},
70
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 25, "POSITION_Y": 0},
71
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
72
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
73
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
74
+ #{"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 25},
75
+ {"TRACK_ID": 2., "FRAME": 2, "POSITION_X": 0, "POSITION_Y": 25}
76
+ ])
77
+ self.tracks_real_intep = pd.DataFrame([{"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
78
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
79
+ {"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 20, "POSITION_Y": 5},
80
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 25, "POSITION_Y": 0},
81
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
82
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
83
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
84
+ {"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 25},
85
+ {"TRACK_ID": 2., "FRAME": 2, "POSITION_X": 0, "POSITION_Y": 25}
86
+ ])
87
+
88
+
89
+ def test_interpolate_tracks_as_expected(self):
90
+ self.interpolated_tracks = interpolate_time_gaps(self.tracks)
91
+ self.assertTrue(np.array_equal(self.interpolated_tracks.to_numpy(), self.tracks_real_intep.to_numpy(), equal_nan=True))
92
+
93
+ class TestTrackExtrapolation(unittest.TestCase):
94
+
95
+ @classmethod
96
+ def setUpClass(self):
97
+
98
+ self.tracks = pd.DataFrame([{"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
99
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
100
+ {"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 20, "POSITION_Y": 5},
101
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 25, "POSITION_Y": 0},
102
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
103
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
104
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
105
+ {"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 25},
106
+ {"TRACK_ID": 2., "FRAME": 2, "POSITION_X": 0, "POSITION_Y": 25}
107
+ ])
108
+ self.tracks_pre_extrapol = pd.DataFrame([
109
+ {"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
110
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
111
+ {"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 20, "POSITION_Y": 5},
112
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 25, "POSITION_Y": 0},
113
+ {"TRACK_ID": 1., "FRAME": 0, "POSITION_X": 5, "POSITION_Y": 20},
114
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
115
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
116
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
117
+ {"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 25},
118
+ {"TRACK_ID": 2., "FRAME": 2, "POSITION_X": 0, "POSITION_Y": 25}
119
+ ])
120
+ self.tracks_post_extrapol = pd.DataFrame([
121
+ {"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
122
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
123
+ {"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 20, "POSITION_Y": 5},
124
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 25, "POSITION_Y": 0},
125
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
126
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
127
+ {"TRACK_ID": 1., "FRAME": 3, "POSITION_X": 10, "POSITION_Y": 25},
128
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
129
+ {"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 25},
130
+ {"TRACK_ID": 2., "FRAME": 2, "POSITION_X": 0, "POSITION_Y": 25},
131
+ {"TRACK_ID": 2., "FRAME": 3, "POSITION_X": 0, "POSITION_Y": 25}
132
+ ])
133
+
134
+ self.tracks_full_extrapol = pd.DataFrame([
135
+ {"TRACK_ID": 0., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 15},
136
+ {"TRACK_ID": 0., "FRAME": 1, "POSITION_X": 15, "POSITION_Y": 10},
137
+ {"TRACK_ID": 0., "FRAME": 2, "POSITION_X": 20, "POSITION_Y": 5},
138
+ {"TRACK_ID": 0., "FRAME": 3, "POSITION_X": 25, "POSITION_Y": 0},
139
+ {"TRACK_ID": 1., "FRAME": 0, "POSITION_X": 5, "POSITION_Y": 20},
140
+ {"TRACK_ID": 1., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 20},
141
+ {"TRACK_ID": 1., "FRAME": 2, "POSITION_X": 10, "POSITION_Y": 25},
142
+ {"TRACK_ID": 1., "FRAME": 3, "POSITION_X": 10, "POSITION_Y": 25},
143
+ {"TRACK_ID": 2., "FRAME": 0, "POSITION_X": 10, "POSITION_Y": 25},
144
+ {"TRACK_ID": 2., "FRAME": 1, "POSITION_X": 5, "POSITION_Y": 25},
145
+ {"TRACK_ID": 2., "FRAME": 2, "POSITION_X": 0, "POSITION_Y": 25},
146
+ {"TRACK_ID": 2., "FRAME": 3, "POSITION_X": 0, "POSITION_Y": 25}
147
+ ])
148
+
149
+
150
+ def test_pre_extrapolate(self):
151
+ self.extrapolated_tracks = extrapolate_tracks(self.tracks,post=False, pre=True)
152
+ self.assertTrue(np.array_equal(self.extrapolated_tracks.to_numpy(), self.tracks_pre_extrapol.to_numpy(), equal_nan=True))
153
+
154
+ def test_post_extrapolate(self):
155
+ self.extrapolated_tracks = extrapolate_tracks(self.tracks,post=True, pre=False)
156
+ self.assertTrue(np.array_equal(self.extrapolated_tracks.to_numpy(), self.tracks_post_extrapol.to_numpy(), equal_nan=True))
157
+
158
+ def test_full_extrapolate(self):
159
+ self.extrapolated_tracks = extrapolate_tracks(self.tracks,post=True, pre=True)
160
+ self.assertTrue(np.array_equal(self.extrapolated_tracks.to_numpy(), self.tracks_full_extrapol.to_numpy(), equal_nan=True))
161
+
162
+
163
+ if __name__=="__main__":
164
+ unittest.main()
tests/test_utils.py ADDED
@@ -0,0 +1,71 @@
1
+ import unittest
2
+ import matplotlib.pyplot as plt
3
+ import numpy as np
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
6
+
7
+ class TestPatchMask(unittest.TestCase):
8
+
9
+ @classmethod
10
+ def setUpClass(self):
11
+ self.radius = 3
12
+
13
+ def test_correct_shape(self):
14
+ self.patch = create_patch_mask(self.radius, self.radius)
15
+ self.assertEqual(self.patch.shape,(3,3))
16
+
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
+
21
+ class TestRemoveRedundantFeatures(unittest.TestCase):
22
+
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']
28
+
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)
31
+
32
+
33
+ class TestExtractChannelIndices(unittest.TestCase):
34
+
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]
40
+
41
+ def test_extracted_channels_are_correct(self):
42
+ self.assertEqual(list(_extract_channel_indices(self.channels, self.required_channels)), self.expected_indices)
43
+
44
+
45
+ class TestImgIndexPerChannel(unittest.TestCase):
46
+
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]
53
+
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)
56
+
57
+
58
+ class TestSplitArrayByRatio(unittest.TestCase):
59
+
60
+ @classmethod
61
+ def setUpClass(self):
62
+ self.array_length = 100
63
+ self.array = np.ones(self.array_length)
64
+
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
+
69
+
70
+ if __name__=="__main__":
71
+ unittest.main()
@@ -1,192 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: celldetective
3
- Version: 1.0.2
4
- Summary: description
5
- Home-page: http://github.com/remyeltorro/celldetective
6
- Author: Rémy Torro
7
- Author-email: remy.torro@inserm.fr
8
- License: GPL-3.0
9
- Description-Content-Type: text/markdown
10
- License-File: LICENSE
11
-
12
- .. raw:: html
13
-
14
- <embed>
15
- <p align="center">
16
- <img src="https://github.com/remyeltorro/celldetective/blob/main/celldetective/icons/logo-large.png" width="33%" />
17
- </p>
18
- </embed>
19
-
20
- |ico1| |ico2| |ico3|
21
-
22
- .. |ico1| image:: https://img.shields.io/readthedocs/celldetective?link=https%3A%2F%2Fcelldetective.readthedocs.io%2Fen%2Flatest%2Findex.html
23
-
24
- .. |ico2| image:: https://img.shields.io/github/forks/remyeltorro/celldetective?link=https%3A%2F%2Fgithub.com%2Fremyeltorro%2Fcelldetective%2Fforks
25
-
26
- .. |ico3| image:: https://img.shields.io/github/stars/remyeltorro/celldetective?link=https%3A%2F%2Fgithub.com%2Fremyeltorro%2Fcelldetective%2Fstargazers
27
-
28
-
29
- Celldetective is a python package and software to perform single-cell analysis on multimodal time lapse microscopy images.
30
-
31
- - **Documentation:** https://celldetective.readthedocs.io
32
- - **Source code:** https://github.com/remyeltorro/celldetective
33
- - **Bug reports:** https://github.com/remyeltorro/celldetective/issues/new/choose
34
- - **Datasets, models and demos:** https://zenodo.org/records/10650279
35
-
36
- Overview
37
- --------
38
-
39
- .. raw:: html
40
-
41
- <embed>
42
- <p align="center">
43
- <img src="https://github.com/remyeltorro/celldetective/blob/main/docs/source/_static/celldetective-blocks.png" width="90%" />
44
- </p>
45
- </embed>
46
-
47
-
48
-
49
- Despite notable efforts in the development of user-friendly softwares that integrate state-of-the-art solutions to perform single cell analysis, very few are designed for time-lapse data and even less for multimodal problems where cells populations are mixed and can only be separated through the use of multimodal information. Few software solutions provide, to our knowledge, the extraction of response functions from single cell events such as the dynamic survival of a population directly in the GUI, as coding skills are usually required to do so. We want to study complex data which is often multimodal time lapse microscopy images of interacting cell populations, without loss of generality. With a high need for an easy-to-use, no-coding-skill-required software adapted to images and intended for biologists, we introduce **Celldetective**, an open-source python-based software with the following highlight features:
50
-
51
- * **Comprehensive single-cell image analysis** : Celldetective ships segmentation, tracking, and measurement modules, as well as event detection from single-cell signals, for up to two populations of interest.
52
- * **Integration of state-of-the-art solutions** : Celldetective harnesses state-of-the-art segmentation techniques (StarDist [#]_, Cellpose [#]_ , [#]_) and tracking algorithm (bTrack [#]_), as well as the napari viewer [#]_ where applicable. These algorithms are interfaced to be well integrated and accessible for the target audience, in the context of complex biological applications.
53
- * **A framework for event description and annotations** : we propose a broad and intuitive framework to annotate and automate the detection of events from single-cell signals through Deep Learning signal classification and regression. The event formulation is directly exploited to define population survival responses.
54
- * **A neighborhood scheme to study cell-cell interactions** : we introduce a neighborhood scheme to relate the spatio-temporal distribution and measurements of two cell populations, allowing the study of how cell-cell interactions affect single-cell and population responses.
55
- * **Deep Learning customization in GUI** : Celldetective facilitates the specialization of Deep Learning models or the creation of new ones adapted to user data, by facilitating the creation of training sets and the training of such models, without having to write a single line of code.
56
- * **In-software analysis** : Celldetective ships visualization tools to collapse single-cell signals with respect to an event, build survival curves, compare measurement distributions across biological conditions.
57
- * **A library of segmentation and signal models**: we created specific models to investigate a co-culture of MCF-7 cells and primary NK cells, that are available directly is the software with a large collection of generalist models developed by the StarDist and Cellpose teams, which are a perfect starting point to segment single cells in a new biological system.
58
- * **Accessible and open source** : Celldetective does not require any coding skills. The software, its models and datasets are made fully open source to encourage transparency and reproducibility.
59
-
60
-
61
- .. raw:: html
62
-
63
- <embed>
64
- <p align="center">
65
- <img src="https://github.com/remyeltorro/celldetective/blob/main/docs/source/_static/signal-annotator.gif" width="90%" />
66
- </p>
67
- </embed>
68
-
69
-
70
-
71
- System requirements
72
- ===================
73
-
74
- Hardware requirements
75
- ---------------------
76
-
77
- The software was tested on several machines, including:
78
-
79
- - An Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz, with a single NVIDIA GeForce RTX 3070 (8 Gb of memory) and 16 Gb of memory
80
- - An Intel(R) Core(TM) i7-9750H CPU @ 2.60 GHz, with 16 Gb of memory
81
-
82
- In GPU mode, succesive segmentation and DL signal analysis could be performed without saturating the GPU memory thanks to the subprocess formulation for the different modules. The GPU can be disabled in the startup window. The software does not require a GPU (but model inference will be longer). A typical analysis of a single movie with a GPU takes between 5 to 15 minutes. Depending on the number of cells and frames on the images, this computation time can increase to the order of half an hour on a CPU.
83
-
84
- The memory must be sufficient to load a movie stack at once in order to visualize it in napari. Otherwise, processing is performed frame by frame, therefore the memory required is extremely low.
85
-
86
- Software requirements
87
- ---------------------
88
-
89
- The software was developed simulateously on Ubuntu 20.04 and Windows 11. It was tested on MacOS, but Tensorflow installation can rquire extra steps.
90
-
91
- - Linux: Ubuntu 20.04.6 LTS (Focal Fossa) (not tested on ulterior versions)
92
- - Windows: Windows 11 Home 23H2
93
-
94
- To use the software, you must install python, *e.g.* through `Anaconda <https://www.anaconda.com/download>`_. We developed and tested the software in Python 3.9.18.
95
-
96
-
97
- Installation
98
- ============
99
-
100
-
101
- Stable release
102
- --------------
103
-
104
- The first release will be available once we open the GitHub repository to the public.
105
-
106
-
107
- Development version
108
- -------------------
109
-
110
- From GitHub
111
- ~~~~~~~~~~~
112
-
113
- Cloning or installing from the GitHub repository will be available once we open the repository to the public.
114
-
115
-
116
- If you want to run the latest development version, you can clone the repository to your local machine and install Celldetective in “development” mode. This means that any changes to the cloned repository will be immediately available in the python environment:
117
-
118
- .. code-block:: bash
119
-
120
- # creates "celldetective" folder
121
- git clone git://github.com/remyeltorro/celldetective.git
122
- cd celldetective
123
-
124
- # install the celldetective package in editable/development mode
125
- pip install -e .
126
-
127
- To run the latest development version without cloning the repository, you can also use this line:
128
-
129
- .. code-block:: bash
130
-
131
- pip install git+https//github.com/remyeltorro/celldetective.git
132
-
133
- From a zip file
134
- ~~~~~~~~~~~~~~~
135
-
136
- You can also download the repository as a compressed file. Unzip the file and open a terminal at the root of the folder (same level as the file requirements.txt). We recommend that you create a python environment as Celldetective relies on many packages that may interfere with package requirements for other projects. Run the following lines to create an environment named "celldetective":
137
-
138
- .. code-block:: bash
139
-
140
- conda create -n celldetective python=3.9.18 pyqt
141
- conda activate celldetective
142
- pip install -r requirements.txt
143
- pip install .
144
-
145
- The installation of the dependencies will take a few minutes (up to half an hour if the network is bad). The Celldetective package itself is light and installs in a few seconds.
146
-
147
- Before launching the software, move to a different directory as running the package locally can create some bugs when locating the models.
148
-
149
-
150
- Documentation
151
- =============
152
-
153
- Read the tutorial here:
154
-
155
- https://celldetective.readthedocs.io/
156
-
157
- How to cite?
158
- ============
159
-
160
- If you use this software in your research, please cite the `Celldetective <https://www.biorxiv.org/content/10.1101/2024.03.15.585250v1>`_ paper (currently preprint):
161
-
162
- .. code-block:: raw
163
-
164
- @article {Torro2024.03.15.585250,
165
- author = {R{\'e}my Torro and Beatriz D{\`\i}az-Bello and Dalia El Arawi and Lorna Ammer and Patrick Chames and Kheya Sengupta and Laurent Limozin},
166
- title = {Celldetective: an AI-enhanced image analysis tool for unraveling dynamic cell interactions},
167
- elocation-id = {2024.03.15.585250},
168
- year = {2024},
169
- doi = {10.1101/2024.03.15.585250},
170
- publisher = {Cold Spring Harbor Laboratory},
171
- abstract = {A current key challenge in bioimaging is the analysis of multimodal and multidimensional data reporting dynamic interactions between diverse cell populations. We developed Celldetective, a software that integrates AI-based segmentation and tracking algorithms and automated signal analysis into a user-friendly graphical interface. It offers complete interactive visualization, annotation, and training capabilities. We demonstrate it by analyzing original experimental data of spreading immune effector cells as well as antibody-dependent cell cytotoxicity events using multimodal fluorescence microscopy.Competing Interest StatementThe authors have declared no competing interest.},
172
- URL = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250},
173
- eprint = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250.full.pdf},
174
- journal = {bioRxiv}
175
- }
176
-
177
-
178
- Make sure you to cite the papers of any segmentation model (StarDist, Cellpose) or tracker (bTrack) you used through Celldetective.
179
-
180
-
181
- Bibliography
182
- ============
183
-
184
- .. [#] Schmidt, U., Weigert, M., Broaddus, C. & Myers, G. Cell Detection with Star-Convex Polygons. in Medical Image Computing and Computer Assisted Intervention – MICCAI 2018 (eds. Frangi, A. F., Schnabel, J. A., Davatzikos, C., Alberola-López, C. & Fichtinger, G.) 265–273 (Springer International Publishing, Cham, 2018). doi:10.1007/978-3-030-00934-2_30.
185
-
186
- .. [#] Stringer, C., Wang, T., Michaelos, M. & Pachitariu, M. Cellpose: a generalist algorithm for cellular segmentation. Nat Methods 18, 100–106 (2021).
187
-
188
- .. [#] Pachitariu, M. & Stringer, C. Cellpose 2.0: how to train your own model. Nat Methods 19, 1634–1641 (2022).
189
-
190
- .. [#] Ulicna, K., Vallardi, G., Charras, G. & Lowe, A. R. Automated Deep Lineage Tree Analysis Using a Bayesian Single Cell Tracking Approach. Frontiers in Computer Science 3, (2021).
191
-
192
- .. [#] Ahlers, J. et al. napari: a multi-dimensional image viewer for Python. Zenodo https://doi.org/10.5281/zenodo.8115575 (2023).
@@ -1,66 +0,0 @@
1
- celldetective/__init__.py,sha256=FEZpJKcskBH2IginYzeqPWoR1lVGuyYCXhv7Hnlkoo8,49
2
- celldetective/__main__.py,sha256=k0Q3v-eQuhW6RtHBS7zE8YDXMLHpcHTXeEP597Gc51o,14033
3
- celldetective/events.py,sha256=ofhxVhnj1j73speaPMYYBu-fWiQR2gzB9sPz-nUs2us,4683
4
- celldetective/extra_properties.py,sha256=9tQiXgkUlhmqyE7gUMgq_Kq-XTWTeeMAtFzDNwSmCgU,3961
5
- celldetective/filters.py,sha256=Cla115fQyQwH-r2ai2XXdA9MEC01VV-Eoo-b0eWMSsE,2668
6
- celldetective/io.py,sha256=5LUGei01YgVvlaWLSsUisWcirWZy-GTxNYOcxtHQONs,73349
7
- celldetective/measure.py,sha256=3iNpf-h4Bmg5--AKuOKtlctq7RhUeGc347iFw_RS7XE,57027
8
- celldetective/neighborhood.py,sha256=R8yyoFlJejZXY5EUZN0PVv_r_SSB6qG4W9Nfp0cKB1Y,30880
9
- celldetective/segmentation.py,sha256=L_dP3n0U4V0QQhQBl-dL5NenE4d04KEYt1zFRlRUvkM,28496
10
- celldetective/signals.py,sha256=p5cXjZv31iwZvCJSexCO3nWeEZVMK_4T4V6zJTJGTFE,104258
11
- celldetective/tracking.py,sha256=pai4bqXYZACrJmji528ZuiX-E_LK7KZFo9aoE-c8egY,37570
12
- celldetective/utils.py,sha256=UkOdMD7ANxxMrJuUwFbHFfp_G43VSZaHE1LXVkzEJEI,59280
13
- celldetective/datasets/segmentation_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- celldetective/datasets/signal_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- celldetective/gui/__init__.py,sha256=vE9BJs32sGtWFE5mIjJiHgWLTNSHSg-J983RoTZ0nmg,921
16
- celldetective/gui/about.py,sha256=i-y54Opb10pKTVNUEcJC-D6Cbiqud2EJ3ZLayXqhdqc,1715
17
- celldetective/gui/analyze_block.py,sha256=0vrZD_XFt6dHa1kovkPZq6HUwIpRAvs0b4E1athcLZU,24199
18
- celldetective/gui/btrack_options.py,sha256=zO_RUdlTn7griKWfiQox3ZxwjeKXd6EBvZKR8IkadQw,35649
19
- celldetective/gui/classifier_widget.py,sha256=zJUgsm1izoFpFrH3bnVR4xarEaLqOPJg96ol9A-flSU,13560
20
- celldetective/gui/configure_new_exp.py,sha256=u2vfxG0PQW26blCUXqLNCypaxtKt3rb1wV6kCDlUDYE,18931
21
- celldetective/gui/control_panel.py,sha256=ZbHp-CL9_YsyK_G5cyZN-ccONHYWU9hVgcGmQkq-wGY,15688
22
- celldetective/gui/gui_utils.py,sha256=TB1JlUchHv9oLc65XyPr652CqYm8_6DbrOpLfhJMgCE,15584
23
- celldetective/gui/json_readers.py,sha256=O-W4ZrKJa7BBBbdU5kw_wRHCC5MvpX5JYLKwQLFbUI4,3620
24
- celldetective/gui/measurement_options.py,sha256=-O--wnCMu7HJ_L2STQ6WRURnv5f79fanuJj73ldeh-0,68074
25
- celldetective/gui/neighborhood_options.py,sha256=0gG8PD9WiGS1bkQLWehi_p1l-C7iavFbpZ-G81l_hzw,16097
26
- celldetective/gui/plot_signals_ui.py,sha256=CqoASv9n6Juncm3bUJ38Q77Jq2M5h_LIaIFlNyKpdpw,43616
27
- celldetective/gui/process_block.py,sha256=4rF_KvP0bC0ez87ikHQ-8oiGs-u_2whnJTH8PwGxaZw,41764
28
- celldetective/gui/retrain_segmentation_model_options.py,sha256=4EsLs-ojPGgssQ_w5r-PWBG-A0YrEI-80TuUBd_f7oE,27208
29
- celldetective/gui/retrain_signal_model_options.py,sha256=joACrotKtCL21CISpJvatzwFg8ptGTs9aCqEZhA4At4,24206
30
- celldetective/gui/seg_model_loader.py,sha256=ZYs1o-UZvv0eM6-Is6rnxRIj__nDDPyM-PWWj83yBes,17167
31
- celldetective/gui/signal_annotator.py,sha256=dN-jGTLXv7oO9IbqJYZYUmIl55pIEgN_hJXKxVeHWrU,98494
32
- celldetective/gui/signal_annotator_options.py,sha256=waK2A8AQU4I62DPFi6yNVgvS0ESlvLaKgcS9ZPKayvU,10801
33
- celldetective/gui/styles.py,sha256=LN_dFF-evDvnHxuDefLtUB3mGYTi0kPmw8swAsbeEis,3874
34
- celldetective/gui/survival_ui.py,sha256=pktIgPlOoO3ZfAe0IJ_OnK5as3Uu0V43GAGQ4vlfsaI,32711
35
- celldetective/gui/tableUI.py,sha256=KP4hV5fvx3UfcV2BhyjHDmdng7NVudMkiJaTcQ5_v6w,20822
36
- celldetective/gui/thresholds_gui.py,sha256=WEfRXM88cZYbKtSz44pMttAV2qVFq1gghDDdehpCNlQ,47172
37
- celldetective/icons/logo-large.png,sha256=FXSwV3u6zEKcfpuSn4unnqB0oUnN9cHqQ9BCKWytrpg,36631
38
- celldetective/icons/logo.png,sha256=wV2OS8_dU5Td5cgdPbCOU3JpMpTwNuYLnfVcnQX0tJA,2437
39
- celldetective/icons/signals_icon.png,sha256=vEiKoqWTtN0-uJgVqtAlwCuP-f4QeWYOlO3sdp2tg2w,3969
40
- celldetective/icons/splash-test.png,sha256=W9smcuuwJUF9DU-rz4aACx7_rCmGRsxYUGPBDlDnrJk,17523
41
- celldetective/icons/splash.png,sha256=J_1jPJylxwHGzGF1xCGocc-BmylHtHTII9VJSLKnezY,17895
42
- celldetective/icons/splash0.png,sha256=qVXsrYUinm5g6-vbHcqwyjh8SIqs9lEqPWnPa1WijaQ,14233
43
- celldetective/icons/survival2.png,sha256=8zsualD7d9VPAecoFA4Om9TFARErqpJzMg6U7XANXf4,4479
44
- celldetective/icons/vignette_signals2.png,sha256=hsVOdQDpEfMGM45aaSeacEm3lvxbquRKKYutiS9qoS0,20743
45
- celldetective/icons/vignette_signals2.svg,sha256=muGNcQudV1jG-bmFd9FwV-Wb8PcrRV5osdZ7pHR7Ekk,5947
46
- celldetective/links/zenodo.json,sha256=7WKRuZY7MHTR-IChWBbU0i47H_479NtlxsCGaJn9-xM,22728
47
- celldetective/models/segmentation_effectors/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
- celldetective/models/segmentation_generic/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
- celldetective/models/segmentation_targets/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- celldetective/models/signal_detection/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
- celldetective/models/tracking_configs/mcf7.json,sha256=iDjb8i6yxs0GleW39dvY3Ld5bZJatlXJrwI8PG3vCT0,1780
52
- celldetective/models/tracking_configs/ricm.json,sha256=L-vmwCR1f89U-qnH2Ms0cBfPFR_dxIWoe2ccH8V-QBA,2727
53
- celldetective/models/tracking_configs/ricm2.json,sha256=DDjJ6ScYcDWvlsy7ujPID8v8H28vcNcMuZmNR8XmGxo,2718
54
- celldetective/scripts/analyze_signals.py,sha256=S7lHgnu8LD2cSUxGsoRRDRUtFydSfHk0vuu25pVUP7I,2030
55
- celldetective/scripts/measure_cells.py,sha256=hcakxsXEv04_FBtJ5HWE4rWMkGlMYjDUHYqqbiiIeFw,10240
56
- celldetective/scripts/segment_cells.py,sha256=wQoLGcTF87WIhz2hBxy3xl3PLc7iQV2P0jjDORATvD0,7494
57
- celldetective/scripts/segment_cells_thresholds.py,sha256=GbWXa6xoO8s4PinJPZIxAuosw4vpzyJ7FiFYpSURojk,4998
58
- celldetective/scripts/track_cells.py,sha256=iPSE7evLniLFxD_pMqq_McwZnFm9c8kzu9tF25ilXSY,7510
59
- celldetective/scripts/train_segmentation_model.py,sha256=dBXq3OOu6F0kWyYcI3K7W_hMUYvndrwKRswBS_-zQnw,8378
60
- celldetective/scripts/train_signal_model.py,sha256=9-dmPCLKJ9ypjsV9AwFd-Sb6B6YaHS0QGT218H5hUPo,1861
61
- celldetective-1.0.2.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
62
- celldetective-1.0.2.dist-info/METADATA,sha256=lSYi7Oo4ViYusO6_N5RY-FixROgdqAyk7q6IDesJSYo,11063
63
- celldetective-1.0.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
64
- celldetective-1.0.2.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
65
- celldetective-1.0.2.dist-info/top_level.txt,sha256=17D0YAVl3CxcdUWAr6HmT2wEAyly2FgZwhSzF1fCZio,14
66
- celldetective-1.0.2.dist-info/RECORD,,