celldetective 1.0.2.post1__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.post1.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.post1.dist-info/METADATA +0 -221
  53. celldetective-1.0.2.post1.dist-info/RECORD +0 -66
  54. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.0.dist-info}/LICENSE +0 -0
  55. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.0.dist-info}/WHEEL +0 -0
  56. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.0.dist-info}/entry_points.txt +0 -0
celldetective/tracking.py CHANGED
@@ -606,7 +606,6 @@ def interpolate_time_gaps(trajectories, column_labels={'track': "TRACK_ID", 'tim
606
606
  trajectories.reset_index(drop=True, inplace=True)
607
607
  trajectories[column_labels['time']] = trajectories[column_labels['time']].astype('int64').astype(float) / 10**9
608
608
  #trajectories[column_labels['time']] = trajectories[column_labels['time']].astype('int64')
609
- print(trajectories[column_labels['time']])
610
609
  trajectories.sort_values(by=[column_labels['track'],column_labels['time']],inplace=True)
611
610
 
612
611
  return trajectories
celldetective/utils.py CHANGED
@@ -367,7 +367,7 @@ def compute_weights(y):
367
367
 
368
368
  return class_weights
369
369
 
370
- def train_test_split(data_x, data_y1, data_y2=None, validation_size=0.25, test_size=0):
370
+ def train_test_split(data_x, data_y1, data_class=None, validation_size=0.25, test_size=0, n_iterations=10):
371
371
 
372
372
  """
373
373
 
@@ -407,37 +407,56 @@ def train_test_split(data_x, data_y1, data_y2=None, validation_size=0.25, test_s
407
407
 
408
408
  """
409
409
 
410
- n_values = len(data_x)
411
- randomize = np.arange(n_values)
412
- np.random.shuffle(randomize)
410
+ if data_class is not None:
411
+ print(f"Unique classes: {np.sort(np.argmax(np.unique(data_class,axis=0),axis=1))}")
413
412
 
414
- train_percentage = 1- validation_size - test_size
415
- chunks = split_by_ratio(randomize, train_percentage, validation_size, test_size)
413
+ for i in range(n_iterations):
416
414
 
417
- x_train = data_x[chunks[0]]
418
- y1_train = data_y1[chunks[0]]
419
- if data_y2 is not None:
420
- y2_train = data_y2[chunks[0]]
415
+ n_values = len(data_x)
416
+ randomize = np.arange(n_values)
417
+ np.random.shuffle(randomize)
421
418
 
419
+ train_percentage = 1 - validation_size - test_size
422
420
 
423
- x_val = data_x[chunks[1]]
424
- y1_val = data_y1[chunks[1]]
425
- if data_y2 is not None:
426
- y2_val = data_y2[chunks[1]]
421
+ chunks = split_by_ratio(randomize, train_percentage, validation_size, test_size)
427
422
 
428
- ds = {"x_train": x_train, "x_val": x_val,
429
- "y1_train": y1_train, "y1_val": y1_val}
430
- if data_y2 is not None:
431
- ds.update({"y2_train": y2_train, "y2_val": y2_val})
423
+ x_train = data_x[chunks[0]]
424
+ y1_train = data_y1[chunks[0]]
425
+ if data_class is not None:
426
+ y2_train = data_class[chunks[0]]
427
+
428
+ x_val = data_x[chunks[1]]
429
+ y1_val = data_y1[chunks[1]]
430
+ if data_class is not None:
431
+ y2_val = data_class[chunks[1]]
432
+
433
+ if data_class is not None:
434
+ print(f"classes in train set: {np.sort(np.argmax(np.unique(y2_train,axis=0),axis=1))}; classes in validation set: {np.sort(np.argmax(np.unique(y2_val,axis=0),axis=1))}")
435
+ same_class_test = np.array_equal(np.sort(np.argmax(np.unique(y2_train,axis=0),axis=1)), np.sort(np.argmax(np.unique(y2_val,axis=0),axis=1)))
436
+ print(f"Check that classes are found in all sets: {same_class_test}...")
437
+ else:
438
+ same_class_test = True
439
+
440
+ if same_class_test:
441
+
442
+ ds = {"x_train": x_train, "x_val": x_val,
443
+ "y1_train": y1_train, "y1_val": y1_val}
444
+ if data_class is not None:
445
+ ds.update({"y2_train": y2_train, "y2_val": y2_val})
446
+
447
+ if test_size>0:
448
+ x_test = data_x[chunks[2]]
449
+ y1_test = data_y1[chunks[2]]
450
+ ds.update({"x_test": x_test, "y1_test": y1_test})
451
+ if data_class is not None:
452
+ y2_test = data_class[chunks[2]]
453
+ ds.update({"y2_test": y2_test})
454
+ return ds
455
+ else:
456
+ continue
457
+
458
+ raise Exception("Some classes are missing from the train or validation set... Abort.")
432
459
 
433
- if test_size>0:
434
- x_test = data_x[chunks[2]]
435
- y1_test = data_y1[chunks[2]]
436
- ds.update({"x_test": x_test, "y1_test": y1_test})
437
- if data_y2 is not None:
438
- y2_test = data_y2[chunks[2]]
439
- ds.update({"y2_test": y2_test})
440
- return ds
441
460
 
442
461
  def remove_redundant_features(features, reference_features, channel_names=None):
443
462
 
@@ -482,7 +501,7 @@ def remove_redundant_features(features, reference_features, channel_names=None):
482
501
 
483
502
  """
484
503
 
485
- new_features = features.copy()
504
+ new_features = features[:]
486
505
 
487
506
  for f in features:
488
507
 
@@ -1201,11 +1220,32 @@ def color_from_class(cclass, recently_modified=False):
1201
1220
  def random_fliprot(img, mask):
1202
1221
 
1203
1222
  """
1223
+ Randomly flips and rotates an image and its corresponding mask.
1224
+
1225
+ This function applies a series of random flips and permutations (rotations) to both the input image and its
1226
+ associated mask, ensuring that any transformations applied to the image are also exactly applied to the mask.
1227
+ The function is designed to handle multi-dimensional images (e.g., multi-channel images in YXC format where
1228
+ channels are last).
1229
+
1230
+ Parameters
1231
+ ----------
1232
+ img : ndarray
1233
+ The input image to be transformed. This array is expected to have dimensions where the channel axis is last.
1234
+ mask : ndarray
1235
+ The mask corresponding to `img`, to be transformed in the same way as the image.
1236
+
1237
+ Returns
1238
+ -------
1239
+ tuple of ndarray
1240
+ A tuple containing the transformed image and mask.
1204
1241
 
1205
- Perform random flipping of the image and the associated mask.
1206
- Needs YXC (channel last).
1242
+ Raises
1243
+ ------
1244
+ AssertionError
1245
+ If the number of dimensions of the mask exceeds that of the image, indicating incompatible shapes.
1207
1246
 
1208
1247
  """
1248
+
1209
1249
  assert img.ndim >= mask.ndim
1210
1250
  axes = tuple(range(mask.ndim))
1211
1251
  perm = tuple(np.random.permutation(axes))
@@ -1225,12 +1265,37 @@ def random_fliprot(img, mask):
1225
1265
  def random_shift(image,mask, max_shift_amplitude=0.1):
1226
1266
 
1227
1267
  """
1268
+ Randomly shifts an image and its corresponding mask along the X and Y axes.
1228
1269
 
1229
- Perform random shift of the image in X and or Y.
1230
- Needs YXC (channel last).
1270
+ This function shifts both the image and the mask by a randomly chosen distance up to a maximum
1271
+ percentage of the image's dimensions, specified by `max_shift_amplitude`. The shifts are applied
1272
+ independently in both the X and Y directions. This type of augmentation can help improve the robustness
1273
+ of models to positional variations in images.
1274
+
1275
+ Parameters
1276
+ ----------
1277
+ image : ndarray
1278
+ The input image to be shifted. Must be in YXC format (height, width, channels).
1279
+ mask : ndarray
1280
+ The mask corresponding to `image`, to be shifted in the same way as the image.
1281
+ max_shift_amplitude : float, optional
1282
+ The maximum shift as a fraction of the image's dimension. Default is 0.1 (10% of the image's size).
1283
+
1284
+ Returns
1285
+ -------
1286
+ tuple of ndarray
1287
+ A tuple containing the shifted image and mask.
1288
+
1289
+ Notes
1290
+ -----
1291
+ - The shift values are chosen randomly within the range defined by the maximum amplitude.
1292
+ - Shifting is performed using the 'constant' mode where missing values are filled with zeros (cval=0.0),
1293
+ which may introduce areas of zero-padding along the edges of the shifted images and masks.
1294
+ - This function is designed to support data augmentation for machine learning and image processing tasks,
1295
+ particularly in contexts where spatial invariance is beneficial.
1296
+
1297
+ """
1231
1298
 
1232
- """
1233
-
1234
1299
  input_shape = image.shape[0]
1235
1300
  max_shift = input_shape*max_shift_amplitude
1236
1301
 
@@ -1249,9 +1314,35 @@ def random_shift(image,mask, max_shift_amplitude=0.1):
1249
1314
 
1250
1315
 
1251
1316
  def blur(x,max_sigma=4.0):
1317
+
1252
1318
  """
1253
- Random image blur
1319
+ Applies a random Gaussian blur to an image.
1320
+
1321
+ This function blurs an image by applying a Gaussian filter with a randomly chosen sigma value. The sigma
1322
+ represents the standard deviation for the Gaussian kernel and is selected randomly up to a specified maximum.
1323
+ The blurring is applied while preserving the range of the image's intensity values and maintaining any
1324
+ zero-valued pixels as they are.
1325
+
1326
+ Parameters
1327
+ ----------
1328
+ x : ndarray
1329
+ The input image to be blurred. The image can have any number of channels, but must be in a format
1330
+ where the channels are the last dimension (YXC format).
1331
+ max_sigma : float, optional
1332
+ The maximum value for the standard deviation of the Gaussian blur. Default is 4.0.
1333
+
1334
+ Returns
1335
+ -------
1336
+ ndarray
1337
+ The blurred image. The output will have the same shape and type as the input image.
1338
+
1339
+ Notes
1340
+ -----
1341
+ - The function ensures that zero-valued pixels in the input image remain unchanged after the blurring,
1342
+ which can be important for maintaining masks or other specific regions within the image.
1343
+ - Gaussian blurring is commonly used in image processing to reduce image noise and detail by smoothing.
1254
1344
  """
1345
+
1255
1346
  sigma = np.random.random()*max_sigma
1256
1347
  loc_i,loc_j,loc_c = np.where(x==0.)
1257
1348
  x = gaussian(x, sigma, channel_axis=-1, preserve_range=True)
@@ -1262,8 +1353,44 @@ def blur(x,max_sigma=4.0):
1262
1353
  def noise(x, apply_probability=0.5, clip_option=False):
1263
1354
 
1264
1355
  """
1265
- Apply random noise to a multichannel image
1356
+ Applies random noise to each channel of a multichannel image based on a specified probability.
1357
+
1358
+ This function introduces various types of random noise to an image. Each channel of the image can be
1359
+ modified independently with different noise models chosen randomly from a predefined list. The application
1360
+ of noise to any given channel is determined by a specified probability, allowing for selective noise
1361
+ addition.
1362
+
1363
+ Parameters
1364
+ ----------
1365
+ x : ndarray
1366
+ The input multichannel image to which noise will be added. The image should be in format with channels
1367
+ as the last dimension (e.g., height x width x channels).
1368
+ apply_probability : float, optional
1369
+ The probability with which noise is applied to each channel of the image. Default is 0.5.
1370
+ clip_option : bool, optional
1371
+ Specifies whether to clip the corrupted data to stay within the valid range after noise addition.
1372
+ If True, the output array will be clipped to the range [0, 1] or [0, 255] depending on the input
1373
+ data type. Default is False.
1374
+
1375
+ Returns
1376
+ -------
1377
+ ndarray
1378
+ The noised image. This output has the same shape as the input but potentially altered intensity values
1379
+ due to noise addition.
1380
+
1381
+ Notes
1382
+ -----
1383
+ - The types of noise that can be applied include 'gaussian', 'localvar', 'poisson', and 'speckle'.
1384
+ - The choice of noise type for each channel is randomized and the noise is only applied if a randomly
1385
+ generated number is less than or equal to `apply_probability`.
1386
+ - Zero-valued pixels in the input image remain zero in the output to preserve background or masked areas.
1266
1387
 
1388
+ Examples
1389
+ --------
1390
+ >>> import numpy as np
1391
+ >>> x = np.random.rand(256, 256, 3) # Example 3-channel image
1392
+ >>> noised_image = noise(x)
1393
+ # The image 'x' may have different types of noise applied to each of its channels with a 50% probability.
1267
1394
  """
1268
1395
 
1269
1396
  x_noise = x.astype(float).copy()
@@ -1678,4 +1805,19 @@ def download_zenodo_file(file, output_dir):
1678
1805
  if file=='db-si-NucCondensation':
1679
1806
  os.rename(os.sep.join([output_dir,'db1-NucCondensation']), os.sep.join([output_dir,file]))
1680
1807
 
1681
- os.remove(path_to_zip_file)
1808
+ os.remove(path_to_zip_file)
1809
+
1810
+ def interpolate_nan(array_like):
1811
+
1812
+ array = array_like.copy()
1813
+
1814
+ isnan_array = ~np.isnan(array)
1815
+
1816
+ xp = isnan_array.ravel().nonzero()[0]
1817
+
1818
+ fp = array[~np.isnan(array)]
1819
+ x = np.isnan(array).ravel().nonzero()[0]
1820
+
1821
+ array[np.isnan(array)] = np.interp(x, xp, fp)
1822
+
1823
+ return array
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.1
2
+ Name: celldetective
3
+ Version: 1.1.0
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,80 @@
1
+ celldetective/__init__.py,sha256=FEZpJKcskBH2IginYzeqPWoR1lVGuyYCXhv7Hnlkoo8,49
2
+ celldetective/__main__.py,sha256=zX2ZDiUp02OlHSwsVUDJ6aCKRAAYU0SSmallsiz1HsA,14054
3
+ celldetective/events.py,sha256=s2pWnR3Z1fcB15sET5WsF2Pi6v6qv16hks_m3WiklNs,3658
4
+ celldetective/extra_properties.py,sha256=9tQiXgkUlhmqyE7gUMgq_Kq-XTWTeeMAtFzDNwSmCgU,3961
5
+ celldetective/filters.py,sha256=i-XN6psgdaG_w6gjK2Qvb1OshspQaDsV_PF1WTyo2Sw,2704
6
+ celldetective/io.py,sha256=nkMj9s8fO_I3J-fVVsuRiEDrJ4nHcdWQqN-9P20DcHQ,80323
7
+ celldetective/measure.py,sha256=5Jr9F9LEj3KzD32ssbPuGgS7sCghRurxYV9e2qjkuj0,56981
8
+ celldetective/neighborhood.py,sha256=WZihWn6npFhe9C_LSmGhLuPevzsvjuscmH-xPLoWO6I,49406
9
+ celldetective/preprocessing.py,sha256=jo5mtCBTh8OwETeGRG89RHjSb3yM_75icA2bMJe35bY,24280
10
+ celldetective/segmentation.py,sha256=L_dP3n0U4V0QQhQBl-dL5NenE4d04KEYt1zFRlRUvkM,28496
11
+ celldetective/signals.py,sha256=q7JSyQolsbCqrClyiigDVKhWGj1KmXkWDrk-VGgvjeY,109452
12
+ celldetective/tracking.py,sha256=uTwCc8saEEHE7bcrv0ML9BNfbiwxUM6DWYK2yBoyzIU,37526
13
+ celldetective/utils.py,sha256=msx-aPX4Uqyrt1jSwzwbq7GIuqkLs8LL3cDqRuTOnQo,65322
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=Ndd6zeTNfo3KqfNeIa7XHX4Cj9GDKq5Qw1LtIsUQBgY,17466
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=6q3mvOEYdvceFYYGtWFKxAJTLKnaGj0FzYhjM3--x6g,26884
26
+ celldetective/gui/measurement_options.py,sha256=L6NETkOM7wucRVuwY4SP7JenQ9bMNGEv-DI3C3t9JW0,52725
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=AQ_Ab6bg2tmvZv5dypbaBqJBML7IE_WlDsrkxL0dXAY,43699
30
+ celldetective/gui/process_block.py,sha256=pI-HDU8_s0_jNNnbRBYj7RZrz7Z6cg6xVYOfrfvdwpc,53564
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=Y7EbLFqINSBA_Cl3_fjGImbfp2PvpFt11pHuqkcT3OM,33537
38
+ celldetective/gui/tableUI.py,sha256=DR2HVTLkR3XYZ_Rkyt7DLObOszuG7rlxyz5d6wIO1Oc,22467
39
+ celldetective/gui/thresholds_gui.py,sha256=vbkiJcBejiqdk45r57Ig38LDyNMqLqqmh1FnaVltxVA,47821
40
+ celldetective/gui/viewers.py,sha256=eN4JevoDGAZGI_QdmRJ3SJRh4_XGUR9BhA_ymAF4xAY,19676
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_generic/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ celldetective/models/segmentation_targets/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ celldetective/models/signal_detection/blank,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
+ celldetective/models/tracking_configs/mcf7.json,sha256=iDjb8i6yxs0GleW39dvY3Ld5bZJatlXJrwI8PG3vCT0,1780
56
+ celldetective/models/tracking_configs/ricm.json,sha256=L-vmwCR1f89U-qnH2Ms0cBfPFR_dxIWoe2ccH8V-QBA,2727
57
+ celldetective/models/tracking_configs/ricm2.json,sha256=DDjJ6ScYcDWvlsy7ujPID8v8H28vcNcMuZmNR8XmGxo,2718
58
+ celldetective/scripts/analyze_signals.py,sha256=23TXGNw-j5xT3ss4mXlnKdBgFLnQ50JUEQOC6_H7Q_0,2203
59
+ celldetective/scripts/measure_cells.py,sha256=4uRG6Dg0WsO-N8ZaBJ4loWOvX6FdHaCblIFXq6Dtirc,11000
60
+ celldetective/scripts/segment_cells.py,sha256=xz1wERezJFF3sI0tS3mRLD7-K0zhEIyAEH60p06DFgU,7660
61
+ celldetective/scripts/segment_cells_thresholds.py,sha256=GbWXa6xoO8s4PinJPZIxAuosw4vpzyJ7FiFYpSURojk,4998
62
+ celldetective/scripts/track_cells.py,sha256=AaNiYEW4osYKKR2kbdVLOUnQEBbcZIA-D0mkhcxPWTY,7985
63
+ celldetective/scripts/train_segmentation_model.py,sha256=dBXq3OOu6F0kWyYcI3K7W_hMUYvndrwKRswBS_-zQnw,8378
64
+ celldetective/scripts/train_signal_model.py,sha256=9-dmPCLKJ9ypjsV9AwFd-Sb6B6YaHS0QGT218H5hUPo,1861
65
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
+ tests/test_events.py,sha256=eLFwwEEJfQAdwhews3-fn1HSvzozcNNFN_Qn0gOvQkE,685
67
+ tests/test_filters.py,sha256=iJksl_HgquqGzPPv46qpNtlD4rkBpZ5eVtIotgZ7LDs,656
68
+ tests/test_io.py,sha256=gk5FmoI7ANEczUtNXYRxc48KzkfYzemwS_eYaLq4_NI,2093
69
+ tests/test_measure.py,sha256=FEUAs1rVHylvIvubCb0bJDNGZLVmkgXNgI3NaGQ1dA8,4542
70
+ tests/test_neighborhood.py,sha256=gk5FmoI7ANEczUtNXYRxc48KzkfYzemwS_eYaLq4_NI,2093
71
+ tests/test_segmentation.py,sha256=-3b7o_fUVMYxfVwX5VHFqRF0dDXObSTtylf5XQGcq1A,3493
72
+ tests/test_signals.py,sha256=No4cah6KxplhDcKXnU8RrA7eDla4hWw6ccf7xGnBokU,3599
73
+ tests/test_tracking.py,sha256=8hebWSqEIuttD1ABn-6dKCT7EXKRR7-4RwyFWi1WPFo,8800
74
+ tests/test_utils.py,sha256=emElC0EgoIeCXnTweZVh-TFT2czu9XSgiRqP9sqFUX8,2175
75
+ celldetective-1.1.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
76
+ celldetective-1.1.0.dist-info/METADATA,sha256=ilgLPeG4uYwEibAGA2uO68p83-eWwP6k7azcQIF8gT4,12412
77
+ celldetective-1.1.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
78
+ celldetective-1.1.0.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
79
+ celldetective-1.1.0.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
80
+ celldetective-1.1.0.dist-info/RECORD,,
tests/__init__.py ADDED
File without changes