celldetective 1.0.2.post1__py3-none-any.whl → 1.1.1__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 (63) hide show
  1. celldetective/__main__.py +7 -21
  2. celldetective/events.py +2 -44
  3. celldetective/extra_properties.py +62 -52
  4. celldetective/filters.py +4 -5
  5. celldetective/gui/__init__.py +1 -1
  6. celldetective/gui/analyze_block.py +37 -10
  7. celldetective/gui/btrack_options.py +24 -23
  8. celldetective/gui/classifier_widget.py +62 -19
  9. celldetective/gui/configure_new_exp.py +32 -35
  10. celldetective/gui/control_panel.py +120 -81
  11. celldetective/gui/gui_utils.py +674 -396
  12. celldetective/gui/json_readers.py +7 -6
  13. celldetective/gui/layouts.py +756 -0
  14. celldetective/gui/measurement_options.py +98 -513
  15. celldetective/gui/neighborhood_options.py +322 -270
  16. celldetective/gui/plot_measurements.py +1114 -0
  17. celldetective/gui/plot_signals_ui.py +21 -20
  18. celldetective/gui/process_block.py +449 -169
  19. celldetective/gui/retrain_segmentation_model_options.py +27 -26
  20. celldetective/gui/retrain_signal_model_options.py +25 -24
  21. celldetective/gui/seg_model_loader.py +31 -27
  22. celldetective/gui/signal_annotator.py +2326 -2295
  23. celldetective/gui/signal_annotator_options.py +18 -16
  24. celldetective/gui/styles.py +16 -1
  25. celldetective/gui/survival_ui.py +67 -39
  26. celldetective/gui/tableUI.py +337 -48
  27. celldetective/gui/thresholds_gui.py +75 -71
  28. celldetective/gui/viewers.py +743 -0
  29. celldetective/io.py +247 -27
  30. celldetective/measure.py +43 -263
  31. celldetective/models/segmentation_effectors/primNK_cfse/config_input.json +29 -0
  32. celldetective/models/segmentation_effectors/primNK_cfse/cp-cfse-transfer +0 -0
  33. celldetective/models/segmentation_effectors/primNK_cfse/training_instructions.json +37 -0
  34. celldetective/neighborhood.py +498 -27
  35. celldetective/preprocessing.py +1023 -0
  36. celldetective/scripts/analyze_signals.py +7 -0
  37. celldetective/scripts/measure_cells.py +12 -0
  38. celldetective/scripts/segment_cells.py +20 -4
  39. celldetective/scripts/track_cells.py +11 -0
  40. celldetective/scripts/train_segmentation_model.py +35 -34
  41. celldetective/segmentation.py +14 -9
  42. celldetective/signals.py +234 -329
  43. celldetective/tracking.py +2 -2
  44. celldetective/utils.py +602 -49
  45. celldetective-1.1.1.dist-info/METADATA +305 -0
  46. celldetective-1.1.1.dist-info/RECORD +84 -0
  47. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/top_level.txt +1 -0
  48. tests/__init__.py +0 -0
  49. tests/test_events.py +28 -0
  50. tests/test_filters.py +24 -0
  51. tests/test_io.py +70 -0
  52. tests/test_measure.py +141 -0
  53. tests/test_neighborhood.py +70 -0
  54. tests/test_preprocessing.py +37 -0
  55. tests/test_segmentation.py +93 -0
  56. tests/test_signals.py +135 -0
  57. tests/test_tracking.py +164 -0
  58. tests/test_utils.py +118 -0
  59. celldetective-1.0.2.post1.dist-info/METADATA +0 -221
  60. celldetective-1.0.2.post1.dist-info/RECORD +0 -66
  61. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/LICENSE +0 -0
  62. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/WHEEL +0 -0
  63. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.1
2
+ Name: celldetective
3
+ Version: 1.1.1
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
+ Requires-Dist: wheel
12
+ Requires-Dist: nbsphinx
13
+ Requires-Dist: nbsphinx-link
14
+ Requires-Dist: sphinx-rtd-theme
15
+ Requires-Dist: sphinx ==5.0.2
16
+ Requires-Dist: jinja2 <3.1
17
+ Requires-Dist: ipykernel
18
+ Requires-Dist: stardist
19
+ Requires-Dist: cellpose <3
20
+ Requires-Dist: scikit-learn
21
+ Requires-Dist: btrack
22
+ Requires-Dist: tensorflow <=2.12.1
23
+ Requires-Dist: napari
24
+ Requires-Dist: tqdm
25
+ Requires-Dist: mahotas
26
+ Requires-Dist: fonticon-materialdesignicons6
27
+ Requires-Dist: art
28
+ Requires-Dist: lifelines
29
+ Requires-Dist: setuptools
30
+ Requires-Dist: scipy
31
+ Requires-Dist: seaborn
32
+ Requires-Dist: opencv-python-headless ==4.7.0.72
33
+ Requires-Dist: liblapack
34
+ Requires-Dist: gputools
35
+ Requires-Dist: lmfit ~=1.2.2
36
+ Requires-Dist: superqt[cmap] >=0.6.1
37
+ Requires-Dist: matplotlib-scalebar
38
+
39
+ # Celldetective
40
+
41
+ <embed>
42
+ <p align="center">
43
+ <img src="https://github.com/remyeltorro/celldetective/blob/main/celldetective/icons/logo-large.png" width="33%" />
44
+ </p>
45
+ </embed>
46
+
47
+ ![ico1](https://img.shields.io/readthedocs/celldetective?link=https%3A%2F%2Fcelldetective.readthedocs.io%2Fen%2Flatest%2Findex.html)
48
+ ![ico17](https://github.com/remyeltorro/celldetective/actions/workflows/test.yml/badge.svg)
49
+ ![ico4](https://img.shields.io/pypi/v/celldetective)
50
+ ![ico6](https://img.shields.io/github/downloads/remyeltorro/celldetective/total)
51
+ ![ico5](https://img.shields.io/pypi/dm/celldetective)
52
+ ![ico2](https://img.shields.io/github/forks/remyeltorro/celldetective?link=https%3A%2F%2Fgithub.com%2Fremyeltorro%2Fcelldetective%2Fforks)
53
+ ![ico3](https://img.shields.io/github/stars/remyeltorro/celldetective?link=https%3A%2F%2Fgithub.com%2Fremyeltorro%2Fcelldetective%2Fstargazers)
54
+
55
+ Celldetective is a python package and software to perform single-cell
56
+ analysis on multimodal time lapse microscopy images.
57
+
58
+ - **Documentation:** <https://celldetective.readthedocs.io>
59
+ - **Source code:** <https://github.com/remyeltorro/celldetective>
60
+ - **Bug reports:**
61
+ <https://github.com/remyeltorro/celldetective/issues/new/choose>
62
+ - **Datasets, models and demos:**
63
+ <https://zenodo.org/records/10650279>
64
+
65
+ ## Overview
66
+
67
+ <embed>
68
+ <p align="center">
69
+ <img src="https://github.com/remyeltorro/celldetective/blob/main/docs/source/_static/celldetective-blocks.png" width="90%" />
70
+ </p>
71
+ </embed>
72
+
73
+ Despite notable efforts in the development of user-friendly softwares
74
+ that integrate state-of-the-art solutions to perform single cell
75
+ analysis, very few are designed for time-lapse data and even less for
76
+ multimodal problems where cells populations are mixed and can only be
77
+ separated through the use of multimodal information. Few software
78
+ solutions provide, to our knowledge, the extraction of response
79
+ functions from single cell events such as the dynamic survival of a
80
+ population directly in the GUI, as coding skills are usually required to
81
+ do so. We want to study complex data which is often multimodal time
82
+ lapse microscopy images of interacting cell populations, without loss of
83
+ generality. With a high need for an easy-to-use,
84
+ no-coding-skill-required software adapted to images and intended for
85
+ biologists, we introduce **Celldetective**, an open-source python-based
86
+ software with the following highlight features:
87
+
88
+ - **Comprehensive single-cell image analysis** : Celldetective ships
89
+ segmentation, tracking, and measurement modules, as well as event
90
+ detection from single-cell signals, for up to two populations of
91
+ interest.
92
+ - **Integration of state-of-the-art solutions** : Celldetective
93
+ harnesses state-of-the-art segmentation techniques (StarDist[^1],
94
+ Cellpose[^2] ,[^3]) and tracking algorithm (bTrack[^4]), as well as
95
+ the napari viewer[^5] where applicable. These algorithms are
96
+ interfaced to be well integrated and accessible for the target
97
+ audience, in the context of complex biological applications.
98
+ - **A framework for event description and annotations** : we propose a
99
+ broad and intuitive framework to annotate and automate the detection
100
+ of events from single-cell signals through Deep Learning signal
101
+ classification and regression. The event formulation is directly
102
+ exploited to define population survival responses.
103
+ - **A neighborhood scheme to study cell-cell interactions** : we
104
+ introduce a neighborhood scheme to relate the spatio-temporal
105
+ distribution and measurements of two cell populations, allowing the
106
+ study of how cell-cell interactions affect single-cell and
107
+ population responses.
108
+ - **Deep Learning customization in GUI** : Celldetective facilitates
109
+ the specialization of Deep Learning models or the creation of new
110
+ ones adapted to user data, by facilitating the creation of training
111
+ sets and the training of such models, without having to write a
112
+ single line of code.
113
+ - **In-software analysis** : Celldetective ships visualization tools
114
+ to collapse single-cell signals with respect to an event, build
115
+ survival curves, compare measurement distributions across biological
116
+ conditions.
117
+ - **A library of segmentation and signal models**: we created specific
118
+ models to investigate a co-culture of MCF-7 cells and primary NK
119
+ cells, that are available directly is the software with a large
120
+ collection of generalist models developed by the StarDist and
121
+ Cellpose teams, which are a perfect starting point to segment single
122
+ cells in a new biological system.
123
+ - **Accessible and open source** : Celldetective does not require any
124
+ coding skills. The software, its models and datasets are made fully
125
+ open source to encourage transparency and reproducibility.
126
+
127
+ <embed>
128
+ <p align="center">
129
+ <img src="https://github.com/remyeltorro/celldetective/blob/main/docs/source/_static/signal-annotator.gif" width="90%" />
130
+ </p>
131
+ </embed>
132
+
133
+ # System requirements
134
+
135
+ ## Hardware requirements
136
+
137
+ The software was tested on several machines, including:
138
+
139
+ - An Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz, with a single NVIDIA
140
+ GeForce RTX 3070 (8 Gb of memory) and 16 Gb of memory
141
+ - An Intel(R) Core(TM) i7-9750H CPU @ 2.60 GHz, with 16 Gb of memory
142
+
143
+ In GPU mode, succesive segmentation and DL signal analysis could be
144
+ performed without saturating the GPU memory thanks to the subprocess
145
+ formulation for the different modules. The GPU can be disabled in the
146
+ startup window. The software does not require a GPU (but model inference
147
+ will be longer). A typical analysis of a single movie with a GPU takes
148
+ between 5 to 15 minutes. Depending on the number of cells and frames on
149
+ the images, this computation time can increase to the order of half an
150
+ hour on a CPU.
151
+
152
+ The memory must be sufficient to load a movie stack at once in order to
153
+ visualize it in napari. Otherwise, processing is performed frame by
154
+ frame, therefore the memory required is extremely low.
155
+
156
+ ## Software requirements
157
+
158
+ The software was developed simulateously on Ubuntu 20.04 and Windows 11.
159
+ It was tested on MacOS, but Tensorflow installation can rquire extra
160
+ steps.
161
+
162
+ - Linux: Ubuntu 20.04.6 LTS (Focal Fossa) (not tested on ulterior
163
+ versions)
164
+ - Windows: Windows 11 Home 23H2
165
+
166
+ To use the software, you must install python, *e.g.* through
167
+ [Anaconda](https://www.anaconda.com/download). We developed and tested
168
+ the software in Python 3.9.18.
169
+
170
+ # Installation
171
+
172
+ ## Stable release
173
+
174
+ Celldetective can be installed with `pip`:
175
+
176
+ ``` bash
177
+ pip install celldetective
178
+ ```
179
+
180
+ We recommend that you create an environment to use Celldetective, *e.g.*
181
+ with `conda`:
182
+
183
+ ``` bash
184
+ conda create -n celldetective python=3.9.18 pyqt
185
+ conda activate celldetective
186
+ pip install celldetective
187
+ ```
188
+
189
+ Need an update? Simply type the following in the terminal (in your
190
+ environment):
191
+
192
+ ``` bash
193
+ pip install --upgrade celldetective
194
+ ```
195
+
196
+ ## Development version
197
+
198
+ ### From GitHub
199
+
200
+ If you want to run the latest development version, you can clone the
201
+ repository to your local machine and install Celldetective in
202
+ "development" mode. This means that any changes to the cloned repository
203
+ will be immediately available in the python environment:
204
+
205
+ ``` bash
206
+ # creates "celldetective" folder
207
+ git clone git://github.com/remyeltorro/celldetective.git
208
+ cd celldetective
209
+
210
+ # install the celldetective package in editable/development mode
211
+ pip install -r requirements.txt
212
+ pip install -e .
213
+ ```
214
+
215
+ To run the latest development version without cloning the repository,
216
+ you can also use this line:
217
+
218
+ ``` bash
219
+ pip install git+https//github.com/remyeltorro/celldetective.git
220
+ ```
221
+
222
+ ### From a zip file
223
+
224
+ You can also download the repository as a compressed file. Unzip the
225
+ file and open a terminal at the root of the folder (same level as the
226
+ file requirements.txt). We recommend that you create a python
227
+ environment as Celldetective relies on many packages that may interfere
228
+ with package requirements for other projects. Run the following lines to
229
+ create an environment named \"celldetective\":
230
+
231
+ ``` bash
232
+ conda create -n celldetective python=3.9.18 pyqt
233
+ conda activate celldetective
234
+ pip install -r requirements.txt
235
+ pip install .
236
+ ```
237
+
238
+ The installation of the dependencies will take a few minutes (up to half
239
+ an hour if the network is bad). The Celldetective package itself is
240
+ light and installs in a few seconds.
241
+
242
+ Before launching the software, move to a different directory as running
243
+ the package locally can create some bugs when locating the models.
244
+
245
+ # Quick start
246
+
247
+ You can launch the GUI by 1) opening a terminal and 2) typing the
248
+ following:
249
+
250
+ ``` bash
251
+ python -m celldetective
252
+ ```
253
+
254
+ # Documentation
255
+
256
+ Read the tutorial here:
257
+
258
+ <https://celldetective.readthedocs.io/>
259
+
260
+ # How to cite?
261
+
262
+ If you use this software in your research, please cite the
263
+ [Celldetective](https://www.biorxiv.org/content/10.1101/2024.03.15.585250v1)
264
+ paper (currently preprint):
265
+
266
+ ``` raw
267
+ @article {Torro2024.03.15.585250,
268
+ 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},
269
+ title = {Celldetective: an AI-enhanced image analysis tool for unraveling dynamic cell interactions},
270
+ elocation-id = {2024.03.15.585250},
271
+ year = {2024},
272
+ doi = {10.1101/2024.03.15.585250},
273
+ publisher = {Cold Spring Harbor Laboratory},
274
+ 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.},
275
+ URL = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250},
276
+ eprint = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250.full.pdf},
277
+ journal = {bioRxiv}
278
+ }
279
+ ```
280
+
281
+ Make sure you to cite the papers of any segmentation model (StarDist,
282
+ Cellpose) or tracker (bTrack) you used through Celldetective.
283
+
284
+ # Bibliography
285
+
286
+ [^1]: Schmidt, U., Weigert, M., Broaddus, C. & Myers, G. Cell Detection
287
+ with Star-Convex Polygons. in Medical Image Computing and Computer
288
+ Assisted Intervention -- MICCAI 2018 (eds. Frangi, A. F., Schnabel,
289
+ J. A., Davatzikos, C., Alberola-López, C. & Fichtinger, G.) 265--273
290
+ (Springer International Publishing, Cham, 2018).
291
+ <doi:10.1007/978-3-030-00934-2_30>.
292
+
293
+ [^2]: Stringer, C., Wang, T., Michaelos, M. & Pachitariu, M. Cellpose: a
294
+ generalist algorithm for cellular segmentation. Nat Methods 18,
295
+ 100--106 (2021).
296
+
297
+ [^3]: Pachitariu, M. & Stringer, C. Cellpose 2.0: how to train your own
298
+ model. Nat Methods 19, 1634--1641 (2022).
299
+
300
+ [^4]: Ulicna, K., Vallardi, G., Charras, G. & Lowe, A. R. Automated Deep
301
+ Lineage Tree Analysis Using a Bayesian Single Cell Tracking
302
+ Approach. Frontiers in Computer Science 3, (2021).
303
+
304
+ [^5]: Ahlers, J. et al. napari: a multi-dimensional image viewer for
305
+ Python. Zenodo <https://doi.org/10.5281/zenodo.8115575> (2023).
@@ -0,0 +1,84 @@
1
+ celldetective/__init__.py,sha256=FEZpJKcskBH2IginYzeqPWoR1lVGuyYCXhv7Hnlkoo8,49
2
+ celldetective/__main__.py,sha256=XFAkq_2cBEkWAVXDGSNFagoQBglyl0Y-GOO3KFc8UqM,13888
3
+ celldetective/events.py,sha256=s2pWnR3Z1fcB15sET5WsF2Pi6v6qv16hks_m3WiklNs,3658
4
+ celldetective/extra_properties.py,sha256=y2SkixGxTOaTz_ghl6RoRnb646t09cgKjB6Pqree0w0,4163
5
+ celldetective/filters.py,sha256=i-XN6psgdaG_w6gjK2Qvb1OshspQaDsV_PF1WTyo2Sw,2704
6
+ celldetective/io.py,sha256=UW0AfnQDLIxfiZ5igk-MoWCYR0N6ePuAsEY-kTOvj58,80460
7
+ celldetective/measure.py,sha256=HDQZfSRx3daOCV5Snu1paYU5JYkwu8engO2qZqhTAUo,48089
8
+ celldetective/neighborhood.py,sha256=QCuhesMHGyr3c3ys9wWcNR1HM6CHdHe51R8upoolgPw,49514
9
+ celldetective/preprocessing.py,sha256=psCs4CAI7gG3YlKvxkXKnpClFL4SjWm5TToXq2ZwL-s,37137
10
+ celldetective/segmentation.py,sha256=2w1OZBg9Ij9C05EMrGVsCpheI2PcykIArFQbxIBIGIM,28978
11
+ celldetective/signals.py,sha256=P7eiDZGGIAYCFBKjGCBi8gMBvJYywxlxZNzyGgw-26Y,102783
12
+ celldetective/tracking.py,sha256=A0mhdF4uq4m8OX1-rhtuhG69rlh_6Pb34Aebu7hIeKM,37601
13
+ celldetective/utils.py,sha256=JQDbZB_VLyVkXfqbROe-m4XjXpkhljYLWMnQf3gbqlU,77509
14
+ celldetective/datasets/segmentation_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ celldetective/datasets/signal_annotations/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ celldetective/gui/__init__.py,sha256=y2dvrUdJi17QMgPjl8WN3XFHYzJpu2ul4_8y7MQV1Bk,941
17
+ celldetective/gui/about.py,sha256=i-y54Opb10pKTVNUEcJC-D6Cbiqud2EJ3ZLayXqhdqc,1715
18
+ celldetective/gui/analyze_block.py,sha256=WD3JQQylx_dVozFCvNqrOyR6LcNHV7R1_gGh7XqOVeI,25423
19
+ celldetective/gui/btrack_options.py,sha256=eQEf63yTUsPCN-d1LqgAMmUQpfv2FH85FqnOSaR-9Q8,35575
20
+ celldetective/gui/classifier_widget.py,sha256=qvRl6svlelGsi-IRa7MrCGXrx4sRI8egl5xdGLH3r1A,15341
21
+ celldetective/gui/configure_new_exp.py,sha256=ANJ-Zn4sjBphtj_aoJu6m1PFEKyv9gxeh9XqS6xOGjk,18969
22
+ celldetective/gui/control_panel.py,sha256=wcDqe4XaDJRMmPmWKJpxd0D9V4_DrdRGnEH6D7B_IK0,17557
23
+ celldetective/gui/gui_utils.py,sha256=PidFfdc8XASeIzZO5pfKgwqe4vROG7-KpYMcBZ42jdw,22673
24
+ celldetective/gui/json_readers.py,sha256=fTrNrlxv9NCae8ZJexBEHxI3yCLRqt6F0Yo1OeDycfA,3686
25
+ celldetective/gui/layouts.py,sha256=qotn6r2feFqc0gZx95ssjxYoxOqms0ZcSWApBrBWYEM,26938
26
+ celldetective/gui/measurement_options.py,sha256=i0CdAfupHJAqhOT7RsufEK919sAzQnFBkQO4IAMYZL0,47704
27
+ celldetective/gui/neighborhood_options.py,sha256=sdKxVRliZtuKSpcPfnFxqkW4V8rN2tzjhDxOPVmElyE,20191
28
+ celldetective/gui/plot_measurements.py,sha256=xUoGxV6uXcen-t4yWtAmcGTUayICI-FxTVKPrWMNlfg,51799
29
+ celldetective/gui/plot_signals_ui.py,sha256=TwWU2u3_mkRNsM8er0kI_kwr5EoZ29YEzlr0cQzyW4A,43732
30
+ celldetective/gui/process_block.py,sha256=7n9glZ1ojEi1bObqwIj4giNhrteT69X1EPMQ1hK63aU,53565
31
+ celldetective/gui/retrain_segmentation_model_options.py,sha256=-rkuUzI_vFFlZC3LAAYEELoJUKcz6PmkpCrxKZindhg,27218
32
+ celldetective/gui/retrain_signal_model_options.py,sha256=uHZy3FGsGMHfZL_nYnuFiXF57XaAMVzjYxVF2OXhYnY,24184
33
+ celldetective/gui/seg_model_loader.py,sha256=uKp8oab-4QdTGqb-tb6bOD-FLD_154GOvgWFYz97BwY,17350
34
+ celldetective/gui/signal_annotator.py,sha256=4ymMpo_GjSBsJSRkyNKrWRLy0EFXHINbFtp9ykDqfGE,84864
35
+ celldetective/gui/signal_annotator_options.py,sha256=-Q7f8eCwniqbgLJqMCa91Wc-V3VHAZidwt7LPd4Z5yU,10879
36
+ celldetective/gui/styles.py,sha256=Vw4wr6MQ4iBwhOY-ZWAxFDZZ3CNohmEnuPPazwhJaho,4129
37
+ celldetective/gui/survival_ui.py,sha256=2JGLC5m6D_gVLwnBAM7uEvuCKw1Cli8nM9i5s7TIpGg,33612
38
+ celldetective/gui/tableUI.py,sha256=fOJXWakqZPQOUp5VydCteg5nrV9DHX24Rq1uoE3mT7Q,31717
39
+ celldetective/gui/thresholds_gui.py,sha256=xVbGw6R9yojZ4iffzM6uR2lMojqVJjoGviCmxzlnEeY,47979
40
+ celldetective/gui/viewers.py,sha256=G8uNb0U_4tJiZkcAWX9BbCSBIUbF4tjedZD-5o4WKxY,27734
41
+ celldetective/icons/logo-large.png,sha256=FXSwV3u6zEKcfpuSn4unnqB0oUnN9cHqQ9BCKWytrpg,36631
42
+ celldetective/icons/logo.png,sha256=wV2OS8_dU5Td5cgdPbCOU3JpMpTwNuYLnfVcnQX0tJA,2437
43
+ celldetective/icons/signals_icon.png,sha256=vEiKoqWTtN0-uJgVqtAlwCuP-f4QeWYOlO3sdp2tg2w,3969
44
+ celldetective/icons/splash-test.png,sha256=W9smcuuwJUF9DU-rz4aACx7_rCmGRsxYUGPBDlDnrJk,17523
45
+ celldetective/icons/splash.png,sha256=J_1jPJylxwHGzGF1xCGocc-BmylHtHTII9VJSLKnezY,17895
46
+ celldetective/icons/splash0.png,sha256=qVXsrYUinm5g6-vbHcqwyjh8SIqs9lEqPWnPa1WijaQ,14233
47
+ celldetective/icons/survival2.png,sha256=8zsualD7d9VPAecoFA4Om9TFARErqpJzMg6U7XANXf4,4479
48
+ celldetective/icons/vignette_signals2.png,sha256=hsVOdQDpEfMGM45aaSeacEm3lvxbquRKKYutiS9qoS0,20743
49
+ celldetective/icons/vignette_signals2.svg,sha256=muGNcQudV1jG-bmFd9FwV-Wb8PcrRV5osdZ7pHR7Ekk,5947
50
+ celldetective/links/zenodo.json,sha256=7WKRuZY7MHTR-IChWBbU0i47H_479NtlxsCGaJn9-xM,22728
51
+ celldetective/models/segmentation_effectors/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
+ celldetective/models/segmentation_effectors/primNK_cfse/config_input.json,sha256=gwEGP5wc6iVcwLrR5IbEb-9lTbdQuPyLLFYXh00374U,509
53
+ celldetective/models/segmentation_effectors/primNK_cfse/cp-cfse-transfer,sha256=ps4BAzGxr2i2R0uBGJqfF9wjg5bIeSeBGQb0YcUChhY,26559970
54
+ celldetective/models/segmentation_effectors/primNK_cfse/training_instructions.json,sha256=DqEO4_oQuQmJkZiefREXz8ts60svoqxIQB-LMScuCnc,909
55
+ celldetective/models/segmentation_generic/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ celldetective/models/segmentation_targets/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ celldetective/models/signal_detection/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ celldetective/models/tracking_configs/mcf7.json,sha256=iDjb8i6yxs0GleW39dvY3Ld5bZJatlXJrwI8PG3vCT0,1780
59
+ celldetective/models/tracking_configs/ricm.json,sha256=L-vmwCR1f89U-qnH2Ms0cBfPFR_dxIWoe2ccH8V-QBA,2727
60
+ celldetective/models/tracking_configs/ricm2.json,sha256=DDjJ6ScYcDWvlsy7ujPID8v8H28vcNcMuZmNR8XmGxo,2718
61
+ celldetective/scripts/analyze_signals.py,sha256=23TXGNw-j5xT3ss4mXlnKdBgFLnQ50JUEQOC6_H7Q_0,2203
62
+ celldetective/scripts/measure_cells.py,sha256=4uRG6Dg0WsO-N8ZaBJ4loWOvX6FdHaCblIFXq6Dtirc,11000
63
+ celldetective/scripts/segment_cells.py,sha256=XbWi2EyhH7vUbUhVR1IPILN2jy5q2AA8T4x44AjTMFE,7874
64
+ celldetective/scripts/segment_cells_thresholds.py,sha256=GbWXa6xoO8s4PinJPZIxAuosw4vpzyJ7FiFYpSURojk,4998
65
+ celldetective/scripts/track_cells.py,sha256=AaNiYEW4osYKKR2kbdVLOUnQEBbcZIA-D0mkhcxPWTY,7985
66
+ celldetective/scripts/train_segmentation_model.py,sha256=UY493QK7_FhS9uHYl2eeEYx7t0kw1jhvc0YMY12YZpI,8614
67
+ celldetective/scripts/train_signal_model.py,sha256=9-dmPCLKJ9ypjsV9AwFd-Sb6B6YaHS0QGT218H5hUPo,1861
68
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
+ tests/test_events.py,sha256=eLFwwEEJfQAdwhews3-fn1HSvzozcNNFN_Qn0gOvQkE,685
70
+ tests/test_filters.py,sha256=iJksl_HgquqGzPPv46qpNtlD4rkBpZ5eVtIotgZ7LDs,656
71
+ tests/test_io.py,sha256=gk5FmoI7ANEczUtNXYRxc48KzkfYzemwS_eYaLq4_NI,2093
72
+ tests/test_measure.py,sha256=FEUAs1rVHylvIvubCb0bJDNGZLVmkgXNgI3NaGQ1dA8,4542
73
+ tests/test_neighborhood.py,sha256=gk5FmoI7ANEczUtNXYRxc48KzkfYzemwS_eYaLq4_NI,2093
74
+ tests/test_preprocessing.py,sha256=FI-Wk-kc4wWmOQg_NLCUIZC1oti396wr5cC-BauBai0,1436
75
+ tests/test_segmentation.py,sha256=-3b7o_fUVMYxfVwX5VHFqRF0dDXObSTtylf5XQGcq1A,3493
76
+ tests/test_signals.py,sha256=No4cah6KxplhDcKXnU8RrA7eDla4hWw6ccf7xGnBokU,3599
77
+ tests/test_tracking.py,sha256=8hebWSqEIuttD1ABn-6dKCT7EXKRR7-4RwyFWi1WPFo,8800
78
+ tests/test_utils.py,sha256=NKRCAC1d89aBK5cWjTb7-pInYow901RrT-uBlIdz4KI,3692
79
+ celldetective-1.1.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
80
+ celldetective-1.1.1.dist-info/METADATA,sha256=oPVbQsTELvlHqiLkqJuE2A6slkrZ5Zimq6rMPNty740,12412
81
+ celldetective-1.1.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
82
+ celldetective-1.1.1.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
83
+ celldetective-1.1.1.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
84
+ celldetective-1.1.1.dist-info/RECORD,,
tests/__init__.py ADDED
File without changes
tests/test_events.py ADDED
@@ -0,0 +1,28 @@
1
+ import unittest
2
+ from celldetective.events import switch_to_events
3
+
4
+ class TestEventSwitch(unittest.TestCase):
5
+
6
+ @classmethod
7
+ def setUpClass(self):
8
+ self.classes = [0,0,1,1,2]
9
+ self.event_times = [5.,8.5,-1,-1,-1]
10
+ self.max_times = [10,10,10,10,10]
11
+ self.origin_times = [0,3,2,1,0]
12
+
13
+ self.expected_events = [1,1,0,0]
14
+ self.expected_times = [5.,5.5,8,9]
15
+
16
+ def test_expected_events(self):
17
+ events, times = switch_to_events(
18
+ self.classes,
19
+ self.event_times,
20
+ self.max_times,
21
+ self.origin_times
22
+ )
23
+ self.assertEqual(events, self.expected_events)
24
+ self.assertEqual(times, self.expected_times)
25
+
26
+
27
+ if __name__=="__main__":
28
+ unittest.main()
tests/test_filters.py ADDED
@@ -0,0 +1,24 @@
1
+ import unittest
2
+ import numpy as np
3
+ from celldetective.filters import gauss_filter, abs_filter
4
+
5
+
6
+ class TestFilters(unittest.TestCase):
7
+
8
+ @classmethod
9
+ def setUpClass(self):
10
+ self.img = np.ones((256,256),dtype=int)
11
+ self.img[100:110,100:110] = 0
12
+ self.gauss_sigma = 1.6
13
+
14
+ def test_gauss_filter_is_float(self):
15
+ self.assertIsInstance(gauss_filter(self.img, self.gauss_sigma)[0,0], float)
16
+
17
+ def test_gauss_filter_has_same_shape(self):
18
+ self.assertEqual(gauss_filter(self.img, self.gauss_sigma).shape, self.img.shape)
19
+
20
+ def test_abs_filter_is_positive(self):
21
+ self.assertTrue(np.all(abs_filter(self.img) >= 0.))
22
+
23
+ if __name__=="__main__":
24
+ unittest.main()
tests/test_io.py ADDED
@@ -0,0 +1,70 @@
1
+ import unittest
2
+ import matplotlib.pyplot as plt
3
+ import numpy as np
4
+ import os
5
+
6
+ # class TestPatchMask(unittest.TestCase):
7
+
8
+ # @classmethod
9
+ # def setUpClass(self):
10
+ # self.radius = 3
11
+
12
+ # def test_correct_shape(self):
13
+ # self.patch = create_patch_mask(self.radius, self.radius)
14
+ # self.assertEqual(self.patch.shape,(3,3))
15
+
16
+ # def test_correct_ring(self):
17
+ # self.patch = create_patch_mask(5, 5,radius=[1,2])
18
+ # self.assertFalse(self.patch[2,2])
19
+
20
+ # class TestRemoveRedundantFeatures(unittest.TestCase):
21
+
22
+ # @classmethod
23
+ # def setUpClass(self):
24
+ # self.list_a = ['feat1','feat2','feat3','feat4','intensity_mean']
25
+ # self.list_b = ['feat5','feat2','feat1','feat6','test_channel_mean']
26
+ # self.expected = ['feat3','feat4']
27
+
28
+ # def test_remove_red_features(self):
29
+ # self.assertEqual(remove_redundant_features(self.list_a, self.list_b, channel_names=['test_channel']), self.expected)
30
+
31
+
32
+ # class TestExtractChannelIndices(unittest.TestCase):
33
+
34
+ # @classmethod
35
+ # def setUpClass(self):
36
+ # self.channels = ['ch1','ch2','ch3','ch4']
37
+ # self.required_channels = ['ch4','ch2']
38
+ # self.expected_indices = [3,1]
39
+
40
+ # def test_extracted_channels_are_correct(self):
41
+ # self.assertEqual(list(_extract_channel_indices(self.channels, self.required_channels)), self.expected_indices)
42
+
43
+
44
+ # class TestImgIndexPerChannel(unittest.TestCase):
45
+
46
+ # @classmethod
47
+ # def setUpClass(self):
48
+ # self.channels_indices = [1]
49
+ # self.len_movie = 5
50
+ # self.nbr_channels = 3
51
+ # self.expected_indices = [1,4,7,10,13]
52
+
53
+ # def test_index_sequence_is_correct(self):
54
+ # self.assertEqual(list(_get_img_num_per_channel(self.channels_indices, self.len_movie, self.nbr_channels)[0]), self.expected_indices)
55
+
56
+
57
+ # class TestSplitArrayByRatio(unittest.TestCase):
58
+
59
+ # @classmethod
60
+ # def setUpClass(self):
61
+ # self.array_length = 100
62
+ # self.array = np.ones(self.array_length)
63
+
64
+ # def test_ratio_split_is_correct(self):
65
+ # split_array = split_by_ratio(self.array,0.5,0.25,0.1)
66
+ # self.assertTrue(np.all([len(split_array[0])==50, len(split_array[1])==25, len(split_array[2])==10]))
67
+
68
+
69
+ # if __name__=="__main__":
70
+ # unittest.main()
tests/test_measure.py ADDED
@@ -0,0 +1,141 @@
1
+ import unittest
2
+ import pandas as pd
3
+ import numpy as np
4
+ from celldetective.measure import measure_features, measure_isotropic_intensity, drop_tonal_features
5
+
6
+ class TestFeatureMeasurement(unittest.TestCase):
7
+
8
+ """
9
+ To do: test spot detection, fluo normalization and peripheral measurements
10
+ """
11
+
12
+ @classmethod
13
+ def setUpClass(self):
14
+
15
+ # Simple mock data, 100px*100px, one channel, value is one, uniform
16
+ # Two objects in labels map
17
+
18
+ self.frame = np.ones((100,100,1), dtype=float)
19
+ self.labels = np.zeros((100,100), dtype=int)
20
+ self.labels[50:55,50:55] = 1
21
+ self.labels[0:10,0:10] = 2
22
+
23
+ self.feature_measurements = measure_features(
24
+ self.frame,
25
+ self.labels,
26
+ features=['intensity_mean','area',],
27
+ channels=['test_channel']
28
+ )
29
+
30
+ self.feature_measurements_no_image = measure_features(
31
+ None,
32
+ self.labels,
33
+ features=['intensity_mean','area',],
34
+ channels=None
35
+ )
36
+
37
+ self.feature_measurements_no_features = measure_features(
38
+ self.frame,
39
+ self.labels,
40
+ features=None,
41
+ channels=['test_channel'],
42
+ )
43
+
44
+ # With image
45
+ def test_measure_yields_table(self):
46
+ self.assertIsInstance(self.feature_measurements, pd.DataFrame)
47
+
48
+ def test_two_objects(self):
49
+ self.assertEqual(len(self.feature_measurements),2)
50
+
51
+ def test_channel_named_correctly(self):
52
+ self.assertIn('test_channel_mean',list(self.feature_measurements.columns))
53
+
54
+ def test_intensity_is_one(self):
55
+ self.assertTrue(np.all([v==1.0 for v in self.feature_measurements['test_channel_mean'].values]))
56
+
57
+ def test_area_first_is_twenty_five(self):
58
+ self.assertEqual(self.feature_measurements['area'].values[0],25)
59
+
60
+ def test_area_second_is_hundred(self):
61
+ self.assertEqual(self.feature_measurements['area'].values[1],100)
62
+
63
+ # Without image
64
+ def test_measure_yields_table(self):
65
+ self.assertIsInstance(self.feature_measurements_no_image, pd.DataFrame)
66
+
67
+ def test_two_objects(self):
68
+ self.assertEqual(len(self.feature_measurements_no_image),2)
69
+
70
+ def test_channel_not_in_table(self):
71
+ self.assertNotIn('test_channel_mean',list(self.feature_measurements_no_image.columns))
72
+
73
+ # With no features
74
+ def test_only_one_measurement(self):
75
+ cols = list(self.feature_measurements_no_features.columns)
76
+ assert 'class_id' in cols and len(cols)==1
77
+
78
+
79
+ class TestIsotropicMeasurement(unittest.TestCase):
80
+
81
+ """
82
+
83
+ Test that isotropic intensity measurements behave as expected on fake image
84
+
85
+ """
86
+
87
+ @classmethod
88
+ def setUpClass(self):
89
+
90
+ # Simple mock data, 100px*100px, one channel, value is one
91
+ # Square (21*21px) of value 0. in middle
92
+ # Two objects in labels map
93
+
94
+ self.frame = np.ones((100,100,1), dtype=float)
95
+ self.frame[40:61,40:61,0] = 0.
96
+ self.positions = pd.DataFrame([{'TRACK_ID': 0, 'POSITION_X': 50, 'POSITION_Y': 50, 'FRAME': 0, 'class_id': 0}])
97
+
98
+ self.inner_radius = 9
99
+ self.upper_radius = 20
100
+ self.safe_upper_radius = int(21//2*np.sqrt(2))+2
101
+
102
+ self.iso_measurements = measure_isotropic_intensity(self.positions,
103
+ self.frame,
104
+ channels=['test_channel'],
105
+ intensity_measurement_radii=[self.inner_radius, self.upper_radius],
106
+ operations = ['mean'],
107
+ )
108
+ self.iso_measurements_ring = measure_isotropic_intensity(
109
+ self.positions,
110
+ self.frame,
111
+ channels=['test_channel'],
112
+ intensity_measurement_radii=[[self.safe_upper_radius, self.safe_upper_radius+3]],
113
+ operations = ['mean'],
114
+ )
115
+
116
+
117
+ def test_measure_yields_table(self):
118
+ self.assertIsInstance(self.iso_measurements, pd.DataFrame)
119
+
120
+ def test_intensity_zero_in_small_circle(self):
121
+ self.assertEqual(self.iso_measurements[f'test_channel_circle_{self.inner_radius}_mean'].values[0],0.)
122
+
123
+ def test_intensity_greater_than_zero_in_intermediate_circle(self):
124
+ self.assertGreater(self.iso_measurements[f'test_channel_circle_{self.upper_radius}_mean'].values[0],0.)
125
+
126
+ def test_ring_measurement_avoids_zero(self):
127
+ self.assertEqual(self.iso_measurements[f'test_channel_ring_{self.safe_upper_radius}_{self.safe_upper_radius+3}_mean'].values[0],1.0)
128
+
129
+ class TestDropTonal(unittest.TestCase):
130
+
131
+ @classmethod
132
+ def setUpClass(self):
133
+ self.features = ['area', 'intensity_mean', 'intensity_max']
134
+
135
+ def test_drop_tonal(self):
136
+ self.features_processed = drop_tonal_features(self.features)
137
+ self.assertEqual(self.features_processed,['area'])
138
+
139
+
140
+ if __name__=="__main__":
141
+ unittest.main()