celldetective 1.3.1__tar.gz → 1.3.3.post1__tar.gz

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 (114) hide show
  1. {celldetective-1.3.1 → celldetective-1.3.3.post1}/PKG-INFO +6 -6
  2. {celldetective-1.3.1 → celldetective-1.3.3.post1}/README.md +5 -5
  3. celldetective-1.3.3.post1/celldetective/_version.py +1 -0
  4. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/events.py +2 -0
  5. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/classifier_widget.py +51 -3
  6. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/control_panel.py +9 -3
  7. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/generic_signal_plot.py +161 -2
  8. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/gui_utils.py +90 -1
  9. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/measurement_options.py +35 -32
  10. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/plot_signals_ui.py +8 -3
  11. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/process_block.py +36 -114
  12. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/retrain_segmentation_model_options.py +3 -1
  13. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/signal_annotator.py +53 -26
  14. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/signal_annotator2.py +17 -30
  15. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/survival_ui.py +7 -3
  16. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/tableUI.py +300 -183
  17. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/thresholds_gui.py +195 -199
  18. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/viewers.py +267 -13
  19. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/io.py +110 -10
  20. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/measure.py +128 -88
  21. celldetective-1.3.3.post1/celldetective/models/segmentation_effectors/ricm_bf_all_last/config_input.json +79 -0
  22. celldetective-1.3.3.post1/celldetective/models/segmentation_effectors/ricm_bf_all_last/ricm_bf_all_last +0 -0
  23. celldetective-1.3.3.post1/celldetective/models/segmentation_effectors/ricm_bf_all_last/training_instructions.json +37 -0
  24. celldetective-1.3.3.post1/celldetective/models/segmentation_effectors/test-transfer/config_input.json +39 -0
  25. celldetective-1.3.3.post1/celldetective/models/segmentation_effectors/test-transfer/test-transfer +0 -0
  26. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/neighborhood.py +154 -69
  27. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/relative_measurements.py +128 -4
  28. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/measure_cells.py +3 -3
  29. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/signals.py +207 -213
  30. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/utils.py +16 -0
  31. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective.egg-info/PKG-INFO +6 -6
  32. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective.egg-info/SOURCES.txt +5 -0
  33. celldetective-1.3.1/celldetective/_version.py +0 -1
  34. {celldetective-1.3.1 → celldetective-1.3.3.post1}/LICENSE +0 -0
  35. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/__init__.py +0 -0
  36. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/__main__.py +0 -0
  37. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/datasets/segmentation_annotations/blank +0 -0
  38. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/datasets/signal_annotations/blank +0 -0
  39. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/extra_properties.py +0 -0
  40. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/filters.py +0 -0
  41. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/InitWindow.py +0 -0
  42. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/__init__.py +0 -0
  43. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/about.py +0 -0
  44. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/analyze_block.py +0 -0
  45. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/btrack_options.py +0 -0
  46. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/configure_new_exp.py +0 -0
  47. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/DL-segmentation-strategy.json +0 -0
  48. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/Threshold-vs-DL.json +0 -0
  49. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/cell-populations.json +0 -0
  50. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/exp-structure.json +0 -0
  51. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/feature-btrack.json +0 -0
  52. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/neighborhood.json +0 -0
  53. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/prefilter-for-segmentation.json +0 -0
  54. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/preprocessing.json +0 -0
  55. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/propagate-classification.json +0 -0
  56. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/track-postprocessing.json +0 -0
  57. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/help/tracking.json +0 -0
  58. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/json_readers.py +0 -0
  59. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/layouts.py +0 -0
  60. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/neighborhood_options.py +0 -0
  61. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/plot_measurements.py +0 -0
  62. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/retrain_signal_model_options.py +0 -0
  63. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/seg_model_loader.py +0 -0
  64. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/signal_annotator_options.py +0 -0
  65. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/gui/styles.py +0 -0
  66. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/logo-large.png +0 -0
  67. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/logo.png +0 -0
  68. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/signals_icon.png +0 -0
  69. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/splash-test.png +0 -0
  70. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/splash.png +0 -0
  71. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/splash0.png +0 -0
  72. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/survival2.png +0 -0
  73. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/vignette_signals2.png +0 -0
  74. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/icons/vignette_signals2.svg +0 -0
  75. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/links/zenodo.json +0 -0
  76. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/pair_signal_detection/blank +0 -0
  77. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/segmentation_effectors/blank +0 -0
  78. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/segmentation_generic/blank +0 -0
  79. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/segmentation_targets/blank +0 -0
  80. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/signal_detection/blank +0 -0
  81. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/tracking_configs/biased_motion.json +0 -0
  82. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/tracking_configs/mcf7.json +0 -0
  83. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/tracking_configs/no_z_motion.json +0 -0
  84. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/tracking_configs/ricm.json +0 -0
  85. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/models/tracking_configs/ricm2.json +0 -0
  86. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/preprocessing.py +0 -0
  87. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/analyze_signals.py +0 -0
  88. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/measure_relative.py +0 -0
  89. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/segment_cells.py +0 -0
  90. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/segment_cells_thresholds.py +0 -0
  91. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/track_cells.py +0 -0
  92. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/train_segmentation_model.py +0 -0
  93. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/scripts/train_signal_model.py +0 -0
  94. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/segmentation.py +0 -0
  95. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective/tracking.py +0 -0
  96. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective.egg-info/dependency_links.txt +0 -0
  97. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective.egg-info/entry_points.txt +0 -0
  98. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective.egg-info/not-zip-safe +0 -0
  99. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective.egg-info/requires.txt +0 -0
  100. {celldetective-1.3.1 → celldetective-1.3.3.post1}/celldetective.egg-info/top_level.txt +0 -0
  101. {celldetective-1.3.1 → celldetective-1.3.3.post1}/setup.cfg +0 -0
  102. {celldetective-1.3.1 → celldetective-1.3.3.post1}/setup.py +0 -0
  103. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/__init__.py +0 -0
  104. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_events.py +0 -0
  105. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_filters.py +0 -0
  106. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_io.py +0 -0
  107. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_measure.py +0 -0
  108. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_neighborhood.py +0 -0
  109. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_preprocessing.py +0 -0
  110. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_qt.py +0 -0
  111. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_segmentation.py +0 -0
  112. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_signals.py +0 -0
  113. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_tracking.py +0 -0
  114. {celldetective-1.3.1 → celldetective-1.3.3.post1}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: celldetective
3
- Version: 1.3.1
3
+ Version: 1.3.3.post1
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -172,20 +172,20 @@ For more information about how to get started, please check the [documentation](
172
172
  # How to cite?
173
173
 
174
174
  If you use this software in your research, please cite the
175
- [Celldetective](https://www.biorxiv.org/content/10.1101/2024.03.15.585250v1)
175
+ [Celldetective](https://www.biorxiv.org/content/10.1101/2024.03.15.585250v3)
176
176
  paper (currently preprint):
177
177
 
178
178
  ``` raw
179
179
  @article {Torro2024.03.15.585250,
180
- 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},
180
+ author = {Torro, R{\'e}my and D{\'\i}az-Bello, Beatriz and Arawi, Dalia El and Dervanova, Ksenija and Ammer, Lorna and Dupuy, Florian and Chames, Patrick and Sengupta, Kheya and Limozin, Laurent},
181
181
  title = {Celldetective: an AI-enhanced image analysis tool for unraveling dynamic cell interactions},
182
182
  elocation-id = {2024.03.15.585250},
183
183
  year = {2024},
184
184
  doi = {10.1101/2024.03.15.585250},
185
185
  publisher = {Cold Spring Harbor Laboratory},
186
- 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.},
187
- URL = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250},
188
- eprint = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250.full.pdf},
186
+ abstract = {A current challenge in bioimaging for immunology and immunotherapy research lies in analyzing multimodal and multidimensional data that capture dynamic interactions between diverse cell populations. Here, we introduce Celldetective, an open-source Python-based software designed for high-performance, end-to-end analysis of image-based in vitro immune and immunotherapy assays. Purpose-built for multicondition, 2D multichannel time-lapse microscopy of mixed cell populations, Celldetective is optimized for the needs of immunology assays. The software seamlessly integrates AI-based segmentation, Bayesian tracking, and automated single-cell event detection, all within an intuitive graphical interface that supports interactive visualization, annotation, and training capabilities. We demonstrate its utility with original data on immune effector cell interactions with an activating surface, mediated by bispecific antibodies, and further showcase its potential for analyzing extensive sets of pairwise interactions in antibody-dependent cell cytotoxicity events.Competing Interest StatementThe authors have declared no competing interest.},
187
+ URL = {https://www.biorxiv.org/content/early/2024/11/13/2024.03.15.585250},
188
+ eprint = {https://www.biorxiv.org/content/early/2024/11/13/2024.03.15.585250.full.pdf},
189
189
  journal = {bioRxiv}
190
190
  }
191
191
  ```
@@ -128,20 +128,20 @@ For more information about how to get started, please check the [documentation](
128
128
  # How to cite?
129
129
 
130
130
  If you use this software in your research, please cite the
131
- [Celldetective](https://www.biorxiv.org/content/10.1101/2024.03.15.585250v1)
131
+ [Celldetective](https://www.biorxiv.org/content/10.1101/2024.03.15.585250v3)
132
132
  paper (currently preprint):
133
133
 
134
134
  ``` raw
135
135
  @article {Torro2024.03.15.585250,
136
- 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},
136
+ author = {Torro, R{\'e}my and D{\'\i}az-Bello, Beatriz and Arawi, Dalia El and Dervanova, Ksenija and Ammer, Lorna and Dupuy, Florian and Chames, Patrick and Sengupta, Kheya and Limozin, Laurent},
137
137
  title = {Celldetective: an AI-enhanced image analysis tool for unraveling dynamic cell interactions},
138
138
  elocation-id = {2024.03.15.585250},
139
139
  year = {2024},
140
140
  doi = {10.1101/2024.03.15.585250},
141
141
  publisher = {Cold Spring Harbor Laboratory},
142
- 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.},
143
- URL = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250},
144
- eprint = {https://www.biorxiv.org/content/early/2024/03/17/2024.03.15.585250.full.pdf},
142
+ abstract = {A current challenge in bioimaging for immunology and immunotherapy research lies in analyzing multimodal and multidimensional data that capture dynamic interactions between diverse cell populations. Here, we introduce Celldetective, an open-source Python-based software designed for high-performance, end-to-end analysis of image-based in vitro immune and immunotherapy assays. Purpose-built for multicondition, 2D multichannel time-lapse microscopy of mixed cell populations, Celldetective is optimized for the needs of immunology assays. The software seamlessly integrates AI-based segmentation, Bayesian tracking, and automated single-cell event detection, all within an intuitive graphical interface that supports interactive visualization, annotation, and training capabilities. We demonstrate its utility with original data on immune effector cell interactions with an activating surface, mediated by bispecific antibodies, and further showcase its potential for analyzing extensive sets of pairwise interactions in antibody-dependent cell cytotoxicity events.Competing Interest StatementThe authors have declared no competing interest.},
143
+ URL = {https://www.biorxiv.org/content/early/2024/11/13/2024.03.15.585250},
144
+ eprint = {https://www.biorxiv.org/content/early/2024/11/13/2024.03.15.585250.full.pdf},
145
145
  journal = {bioRxiv}
146
146
  }
147
147
  ```
@@ -0,0 +1 @@
1
+ __version__ = "1.3.3.post1"
@@ -104,6 +104,8 @@ def switch_to_events(classes, event_times, max_times, origin_times=None, left_ce
104
104
  pass
105
105
  elif c==1:
106
106
  delta_t = mt - ot
107
+ if cut_observation_time is not None:
108
+ delta_t = cut_observation_time - ot
107
109
  if delta_t>0:
108
110
  events.append(0)
109
111
  survival_times.append(delta_t)
@@ -253,6 +253,24 @@ class ClassifierWidget(QWidget, Styles):
253
253
 
254
254
  def update_props_scatter(self, feature_changed=True):
255
255
 
256
+ try:
257
+ if np.any(self.df[self.features_cb[0].currentText()].to_numpy() <= 0.):
258
+ if self.ax_props.get_yscale()=='log':
259
+ self.log_btns[0].click()
260
+ self.log_btns[0].setEnabled(False)
261
+ else:
262
+ self.log_btns[0].setEnabled(True)
263
+
264
+ if np.any(self.df[self.features_cb[1].currentText()].to_numpy() <= 0.):
265
+ if self.ax_props.get_xscale()=='log':
266
+ self.log_btns[1].click()
267
+ self.log_btns[1].setEnabled(False)
268
+ else:
269
+ self.log_btns[1].setEnabled(True)
270
+ except Exception as e:
271
+ #print(e)
272
+ pass
273
+
256
274
  class_name = self.class_name
257
275
 
258
276
  try:
@@ -279,11 +297,24 @@ class ClassifierWidget(QWidget, Styles):
279
297
  max_x = self.df.dropna(subset=feat_x)[feat_x].max()
280
298
  min_y = self.df.dropna(subset=feat_y)[feat_y].min()
281
299
  max_y = self.df.dropna(subset=feat_y)[feat_y].max()
300
+
301
+ x_padding = (max_x - min_x) * 0.05
302
+ y_padding = (max_y - min_y) * 0.05
303
+ if x_padding==0:
304
+ x_padding = 0.05
305
+ if y_padding==0:
306
+ y_padding = 0.05
282
307
 
283
308
  if min_x==min_x and max_x==max_x:
284
- self.ax_props.set_xlim(min_x, max_x)
309
+ if self.ax_props.get_xscale()=='linear':
310
+ self.ax_props.set_xlim(min_x - x_padding, max_x + x_padding)
311
+ else:
312
+ self.ax_props.set_xlim(min_x, max_x)
285
313
  if min_y==min_y and max_y==max_y:
286
- self.ax_props.set_ylim(min_y, max_y)
314
+ if self.ax_props.get_yscale()=='linear':
315
+ self.ax_props.set_ylim(min_y - y_padding, max_y + y_padding)
316
+ else:
317
+ self.ax_props.set_ylim(min_y, max_y)
287
318
 
288
319
  self.propscanvas.canvas.toolbar.update()
289
320
 
@@ -452,22 +483,39 @@ class ClassifierWidget(QWidget, Styles):
452
483
 
453
484
  if i==1:
454
485
  try:
486
+ feat_x = self.features_cb[1].currentText()
487
+ min_x = self.df.dropna(subset=feat_x)[feat_x].min()
488
+ max_x = self.df.dropna(subset=feat_x)[feat_x].max()
489
+ x_padding = (max_x - min_x) * 0.05
490
+ if x_padding==0:
491
+ x_padding = 0.05
492
+
455
493
  if self.ax_props.get_xscale()=='linear':
494
+ self.ax_props.set_xlim(min_x, max_x)
456
495
  self.ax_props.set_xscale('log')
457
496
  self.log_btns[i].setIcon(icon(MDI6.math_log,color="#1565c0"))
458
497
  else:
459
498
  self.ax_props.set_xscale('linear')
499
+ self.ax_props.set_xlim(min_x - x_padding, max_x + x_padding)
460
500
  self.log_btns[i].setIcon(icon(MDI6.math_log,color="black"))
461
501
  except Exception as e:
462
502
  print(e)
463
503
  elif i==0:
464
504
  try:
505
+ feat_y = self.features_cb[0].currentText()
506
+ min_y = self.df.dropna(subset=feat_y)[feat_y].min()
507
+ max_y = self.df.dropna(subset=feat_y)[feat_y].max()
508
+ y_padding = (max_y - min_y) * 0.05
509
+ if y_padding==0:
510
+ y_padding = 0.05
511
+
465
512
  if self.ax_props.get_yscale()=='linear':
466
- ymin,ymax = self.ax_props.get_ylim()
513
+ self.ax_props.set_ylim(min_y, max_y)
467
514
  self.ax_props.set_yscale('log')
468
515
  self.log_btns[i].setIcon(icon(MDI6.math_log,color="#1565c0"))
469
516
  else:
470
517
  self.ax_props.set_yscale('linear')
518
+ self.ax_props.set_ylim(min_y - y_padding, max_y + y_padding)
471
519
  self.log_btns[i].setIcon(icon(MDI6.math_log,color="black"))
472
520
  except Exception as e:
473
521
  print(e)
@@ -181,7 +181,13 @@ class ControlPanel(QMainWindow, Styles):
181
181
  exp_hbox = QHBoxLayout()
182
182
  exp_hbox.addWidget(experiment_label, 25, alignment=Qt.AlignRight)
183
183
  exp_subhbox = QHBoxLayout()
184
- exp_subhbox.addWidget(QLabel(name), 90, alignment=Qt.AlignLeft)
184
+ if len(name)>thresh:
185
+ name_cut = name[:thresh - 3]+'...'
186
+ else:
187
+ name_cut = name
188
+ exp_name_lbl = QLabel(name_cut)
189
+ exp_name_lbl.setToolTip(name)
190
+ exp_subhbox.addWidget(exp_name_lbl, 90, alignment=Qt.AlignLeft)
185
191
  exp_subhbox.addWidget(self.folder_exp_btn, 5, alignment=Qt.AlignRight)
186
192
  exp_subhbox.addWidget(self.edit_config_button, 5, alignment=Qt.AlignRight)
187
193
  exp_hbox.addLayout(exp_subhbox, 75)
@@ -444,8 +450,8 @@ class ControlPanel(QMainWindow, Styles):
444
450
  self.view_stack_btn.setEnabled(False)
445
451
  self.ProcessEffectors.signal_analysis_action.setEnabled(True)
446
452
  self.ProcessTargets.signal_analysis_action.setEnabled(True)
447
-
448
- self.delete_tracks_btn.hide()
453
+ if hasattr(self,'delete_tracks_btn'):
454
+ self.delete_tracks_btn.hide()
449
455
  self.ProcessTargets.delete_tracks_btn.hide()
450
456
  self.ProcessEffectors.delete_tracks_btn.hide()
451
457
  else:
@@ -5,7 +5,11 @@ from PyQt5.QtCore import Qt, QSize
5
5
  from PyQt5.QtGui import QDoubleValidator
6
6
 
7
7
  from celldetective.gui.gui_utils import center_window, FigureCanvas, ExportPlotBtn
8
+ from celldetective.gui.tableUI import TableUI
9
+ from celldetective.io import collect_experiment_metadata
10
+
8
11
  from superqt.fonticon import icon
12
+ from superqt import QLabeledSlider
9
13
  from fonticon_mdi6 import MDI6
10
14
  import numpy as np
11
15
  import json
@@ -16,7 +20,9 @@ from glob import glob
16
20
  from matplotlib.cm import tab10
17
21
  from celldetective.gui import Styles
18
22
  import matplotlib.cm as mcm
23
+ import pandas as pd
19
24
 
25
+ from lifelines.utils import qth_survival_times
20
26
 
21
27
  class GenericSignalPlotWidget(QWidget, Styles):
22
28
 
@@ -136,6 +142,14 @@ class GenericSignalPlotWidget(QWidget, Styles):
136
142
  plot_buttons_hbox.addWidget(self.export_btn, 5, alignment=Qt.AlignRight)
137
143
  self.layout.addLayout(plot_buttons_hbox)
138
144
 
145
+ self.export_tabular_btn = QPushButton('')
146
+ self.export_tabular_btn.setIcon(icon(MDI6.table,color="black"))
147
+ self.export_tabular_btn.setStyleSheet(self.button_select_all)
148
+ self.export_tabular_btn.setToolTip('Tabulate survival values.')
149
+ self.export_tabular_btn.setIconSize(QSize(20, 20))
150
+ plot_buttons_hbox.addWidget(self.export_tabular_btn, 5, alignment=Qt.AlignRight)
151
+ self.export_tabular_btn.hide()
152
+
139
153
  self.ax.set_prop_cycle('color',[self.cmap(i) for i in np.linspace(0, 1, len(self.parent_window.well_indices))])
140
154
 
141
155
  self.fig.set_facecolor('none') # or 'None'
@@ -671,7 +685,9 @@ class SurvivalPlotWidget(GenericSignalPlotWidget):
671
685
  self.class_selection_widget.hide()
672
686
  self.rescale_widget.hide()
673
687
  self.cell_lines_alpha_wdg.hide()
674
-
688
+ self.export_tabular_btn.show()
689
+ self.export_tabular_btn.clicked.connect(self.set_table_options)
690
+
675
691
  def switch_to_log(self):
676
692
 
677
693
  """
@@ -790,4 +806,147 @@ class SurvivalPlotWidget(GenericSignalPlotWidget):
790
806
 
791
807
  # Plot a signal
792
808
  if line==line:
793
- line.plot_survival_function(ci_show=ci_option, ax=self.ax, legend=legend, color=color, label=label, xlabel='timeline [min]')
809
+ line.plot_survival_function(ci_show=ci_option, ax=self.ax, legend=legend, color=color, label=label, xlabel='timeline [min]')
810
+
811
+ def set_table_options(self):
812
+
813
+ self.config_table_wg = QWidget()
814
+ self.config_table_wg.setMinimumWidth(480)
815
+ self.config_table_wg.setWindowTitle('Survival data')
816
+
817
+ layout = QVBoxLayout()
818
+ self.config_table_wg.setLayout(layout)
819
+
820
+ self.all_values_rb = QRadioButton('tabulate all values')
821
+ self.single_timepoint_rb = QRadioButton('survival at single timepoint [min]: ')
822
+ self.ec_rb = QRadioButton(r'EC N% survival: ')
823
+ self.all_values_rb.toggled.connect(self.activate_sliders)
824
+ self.single_timepoint_rb.toggled.connect(self.activate_sliders)
825
+
826
+ self.single_timepoint_slider = QLabeledSlider()
827
+ self.single_timepoint_slider.setRange(0, int(self.df['FRAME'].max()*self.parent_window.FrameToMin))
828
+ self.single_timepoint_slider.setValue(int(self.df['FRAME'].max()*self.parent_window.FrameToMin))
829
+
830
+ self.ec_slider = QLabeledSlider()
831
+ self.ec_slider.setRange(0, 100)
832
+ self.ec_slider.setValue(50)
833
+
834
+ self.ec_rb.toggled.connect(self.activate_sliders)
835
+ self.all_values_rb.click()
836
+
837
+ self.set_btn = QPushButton('Set')
838
+ self.set_btn.setStyleSheet(self.button_style_sheet)
839
+ self.set_btn.clicked.connect(self.assemble_survival_data)
840
+
841
+ layout.addWidget(self.all_values_rb)
842
+
843
+ single_tp_layout = QHBoxLayout()
844
+ single_tp_layout.addWidget(self.single_timepoint_rb, 33)
845
+ single_tp_layout.addWidget(self.single_timepoint_slider, 66)
846
+ layout.addLayout(single_tp_layout)
847
+
848
+ ec_layout = QHBoxLayout()
849
+ ec_layout.addWidget(self.ec_rb, 33)
850
+ ec_layout.addWidget(self.ec_slider, 66)
851
+ layout.addLayout(ec_layout)
852
+
853
+ layout.addWidget(self.set_btn)
854
+ center_window(self.config_table_wg)
855
+ self.config_table_wg.show()
856
+
857
+ def activate_sliders(self):
858
+ if self.all_values_rb.isChecked():
859
+ self.single_timepoint_slider.setEnabled(False)
860
+ self.ec_slider.setEnabled(False)
861
+ elif self.single_timepoint_rb.isChecked():
862
+ self.single_timepoint_slider.setEnabled(True)
863
+ self.ec_slider.setEnabled(False)
864
+ elif self.ec_rb.isChecked():
865
+ self.ec_slider.setEnabled(True)
866
+ self.single_timepoint_slider.setEnabled(False)
867
+
868
+ def assemble_survival_data(self):
869
+
870
+ if self.plot_options[0].isChecked():
871
+ data = self.df_well_info
872
+ groupby = ['well_path']
873
+ if self.plot_options[1].isChecked():
874
+ data = self.df_pos_info
875
+ groupby = ['pos_path']
876
+ if self.plot_options[2].isChecked():
877
+ print('Not implemented yet... Please select "well" or "position" as grouping...')
878
+ return None
879
+
880
+ if self.all_values_rb.isChecked():
881
+
882
+ survival_table = []
883
+ tid=0
884
+ for name,group in data.groupby(groupby):
885
+ print(name)
886
+ if groupby[0]=="pos_path":
887
+ metadata = collect_experiment_metadata(pos_path=name[0])
888
+ elif groupby[0]=="well_path":
889
+ metadata = collect_experiment_metadata(well_path=name[0])
890
+ ks_estimator = group['survival_fit'].values[0]
891
+ if ks_estimator!=ks_estimator:
892
+ continue
893
+ timeline = list(ks_estimator.survival_function_.index)
894
+ survival = ks_estimator.survival_function_['KM_estimate'].values
895
+ lower_error = ks_estimator.confidence_interval_['KM_estimate_lower_0.95'].values
896
+ upper_error = ks_estimator.confidence_interval_['KM_estimate_upper_0.95'].values
897
+ for k in range(len(timeline)):
898
+ dico = metadata.copy()
899
+ dico.update({'TRACK_ID': tid,'FRAME': int(timeline[k] / self.parent_window.FrameToMin),'timeline': timeline[k], 'survival': survival[k], "event_fraction": 1-survival[k], 'KM_estimate_lower_0.95': lower_error[k], 'KM_estimate_upper_0.95': upper_error[k]})
900
+ survival_table.append(dico)
901
+ tid+=1
902
+
903
+ survival_table = pd.DataFrame(survival_table)
904
+ self.table = TableUI(survival_table, f"Survival data", plot_mode="plot_track_signals")
905
+ self.table.show()
906
+
907
+ elif self.single_timepoint_rb.isChecked():
908
+
909
+ survival_table = []
910
+ tid=0
911
+ for name,group in data.groupby(groupby):
912
+ print(name)
913
+ if groupby[0]=="pos_path":
914
+ metadata = collect_experiment_metadata(pos_path=name[0])
915
+ elif groupby[0]=="well_path":
916
+ metadata = collect_experiment_metadata(well_path=name[0])
917
+ ks_estimator = group['survival_fit'].values[0]
918
+ if ks_estimator!=ks_estimator:
919
+ continue
920
+ survival = ks_estimator.survival_function_at_times(self.single_timepoint_slider.value()).values[0]
921
+ dico = metadata.copy()
922
+ dico.update({'timepoint': self.single_timepoint_slider.value(), 'survival': survival, 'event_fraction': 1 - survival})
923
+ survival_table.append(dico)
924
+ tid+=1
925
+
926
+ survival_table = pd.DataFrame(survival_table)
927
+ self.table = TableUI(survival_table, f"Survival data", plot_mode="static")
928
+ self.table.show()
929
+
930
+ elif self.ec_rb.isChecked():
931
+
932
+ survival_table = []
933
+ tid=0
934
+ for name,group in data.groupby(groupby):
935
+ print(name)
936
+ if groupby[0]=="pos_path":
937
+ metadata = collect_experiment_metadata(pos_path=name[0])
938
+ elif groupby[0]=="well_path":
939
+ metadata = collect_experiment_metadata(well_path=name[0])
940
+ ks_estimator = group['survival_fit'].values[0]
941
+ if ks_estimator!=ks_estimator:
942
+ continue
943
+ survival = ks_estimator.survival_function_
944
+ ecN = qth_survival_times(float(self.ec_slider.value())/100.0, survival)
945
+ dico = metadata.copy()
946
+ dico.update({"qth": int(self.ec_slider.value()), f'EC{int(self.ec_slider.value())}% [min]': ecN})
947
+ survival_table.append(dico)
948
+ tid+=1
949
+
950
+ survival_table = pd.DataFrame(survival_table)
951
+ self.table = TableUI(survival_table, f"Survival data", plot_mode="static")
952
+ self.table.show()
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
  from PyQt5.QtWidgets import QApplication, QMessageBox, QFrame, QSizePolicy, QWidget, QLineEdit, QListWidget, QVBoxLayout, QComboBox, \
3
3
  QPushButton, QLabel, QHBoxLayout, QCheckBox, QFileDialog
4
- from PyQt5.QtCore import Qt, QSize
4
+ from PyQt5.QtCore import Qt, QSize, QAbstractTableModel
5
5
  from PyQt5.QtGui import QDoubleValidator, QIntValidator
6
6
 
7
7
  from celldetective.gui import Styles
@@ -16,6 +16,95 @@ from inspect import getmembers, isfunction
16
16
  from celldetective.filters import *
17
17
  from os import sep
18
18
 
19
+ class PandasModel(QAbstractTableModel):
20
+
21
+ """
22
+ from https://stackoverflow.com/questions/31475965/fastest-way-to-populate-qtableview-from-pandas-data-frame
23
+ """
24
+
25
+ def __init__(self, data):
26
+ QAbstractTableModel.__init__(self)
27
+ self._data = data
28
+ self.colors = dict()
29
+
30
+ def rowCount(self, parent=None):
31
+ return self._data.shape[0]
32
+
33
+ def columnCount(self, parent=None):
34
+ return self._data.shape[1]
35
+
36
+ def data(self, index, role=Qt.DisplayRole):
37
+ if index.isValid():
38
+ if role == Qt.DisplayRole:
39
+ return str(self._data.iloc[index.row(), index.column()])
40
+ if role == Qt.BackgroundRole:
41
+ color = self.colors.get((index.row(), index.column()))
42
+ if color is not None:
43
+ return color
44
+ return None
45
+
46
+ def headerData(self, rowcol, orientation, role):
47
+ if orientation == Qt.Horizontal and role == Qt.DisplayRole:
48
+ return self._data.columns[rowcol]
49
+ if orientation == Qt.Vertical and role == Qt.DisplayRole:
50
+ return self._data.index[rowcol]
51
+ return None
52
+
53
+ def change_color(self, row, column, color):
54
+ ix = self.index(row, column)
55
+ self.colors[(row, column)] = color
56
+ self.dataChanged.emit(ix, ix, (Qt.BackgroundRole,))
57
+
58
+
59
+ class GenericOpColWidget(QWidget, Styles):
60
+
61
+ def __init__(self, parent_window, column=None, title=''):
62
+
63
+ super().__init__()
64
+
65
+ self.parent_window = parent_window
66
+ self.column = column
67
+ self.title = title
68
+
69
+ self.setWindowTitle(self.title)
70
+ # Create the QComboBox and add some items
71
+
72
+ self.layout = QVBoxLayout(self)
73
+ self.layout.setContentsMargins(30,30,30,30)
74
+
75
+ self.sublayout = QVBoxLayout()
76
+
77
+ self.measurements_cb = QComboBox()
78
+ self.measurements_cb.addItems(list(self.parent_window.data.columns))
79
+ if self.column is not None:
80
+ idx = self.measurements_cb.findText(self.column)
81
+ self.measurements_cb.setCurrentIndex(idx)
82
+
83
+ measurement_layout = QHBoxLayout()
84
+ measurement_layout.addWidget(QLabel('measurements: '), 25)
85
+ measurement_layout.addWidget(self.measurements_cb, 75)
86
+ self.sublayout.addLayout(measurement_layout)
87
+
88
+ self.layout.addLayout(self.sublayout)
89
+
90
+ self.submit_btn = QPushButton('Compute')
91
+ self.submit_btn.setStyleSheet(self.button_style_sheet)
92
+ self.submit_btn.clicked.connect(self.launch_operation)
93
+ self.layout.addWidget(self.submit_btn, 30)
94
+
95
+ self.setAttribute(Qt.WA_DeleteOnClose)
96
+ center_window(self)
97
+
98
+ def launch_operation(self):
99
+
100
+ self.compute()
101
+ self.parent_window.model = PandasModel(self.parent_window.data)
102
+ self.parent_window.table_view.setModel(self.parent_window.model)
103
+ self.close()
104
+
105
+ def compute(self):
106
+ pass
107
+
19
108
 
20
109
  class QuickSliderLayout(QHBoxLayout):
21
110
 
@@ -10,7 +10,7 @@ from superqt import QLabeledDoubleSlider
10
10
  from superqt.fonticon import icon
11
11
  from fonticon_mdi6 import MDI6
12
12
 
13
- from celldetective.gui.thresholds_gui import ThresholdSpot
13
+ #from celldetective.gui.thresholds_gui import ThresholdSpot
14
14
  from celldetective.utils import extract_experiment_channels, get_software_location
15
15
  from celldetective.io import load_frames, auto_load_number_of_frames
16
16
  from celldetective.measure import compute_haralick_features
@@ -26,7 +26,7 @@ from tifffile import imread
26
26
  from pathlib import Path
27
27
  import gc
28
28
 
29
- from celldetective.gui.viewers import CellEdgeVisualizer
29
+ from celldetective.gui.viewers import CellEdgeVisualizer, SpotDetectionVisualizer
30
30
  from celldetective.gui.layouts import ProtocolDesignerLayout, BackgroundFitCorrectionLayout, LocalCorrectionLayout
31
31
  from celldetective.gui.gui_utils import ThresholdLineEdit
32
32
  from celldetective.gui import Styles
@@ -951,51 +951,54 @@ class ConfigMeasurements(QMainWindow, Styles):
951
951
 
952
952
  layout.addWidget(self.threshold_lbl, 4, 0)
953
953
  layout.addWidget(self.threshold_value, 4, 1)
954
- self.preview_spot = QPushButton('Preview')
955
- self.preview_spot.clicked.connect(self.spot_preview)
956
- self.preview_spot.setStyleSheet(self.button_style_sheet_2)
957
- layout.addWidget(self.preview_spot, 5, 0, 1, 2)
958
- self.spot_channel.setEnabled(False)
959
- self.spot_channel_lbl.setEnabled(False)
960
- self.diameter_value.setEnabled(False)
961
- self.diameter_lbl.setEnabled(False)
962
- self.threshold_value.setEnabled(False)
963
- self.threshold_lbl.setEnabled(False)
964
- self.preview_spot.setEnabled(False)
965
954
 
955
+ self.spot_viewer_btn = QPushButton()
956
+ self.spot_viewer_btn.clicked.connect(self.spot_preview)
957
+ self.spot_viewer_btn.setIcon(icon(MDI6.image_check, color="k"))
958
+ self.spot_viewer_btn.setStyleSheet(self.button_select_all)
959
+ self.spot_viewer_btn.setToolTip('Set detection parameters visually.')
960
+ layout.addWidget(self.spot_viewer_btn, 1, 1, 1, 1, alignment=Qt.AlignRight)
961
+
962
+ self.spot_detection_widgets = [self.spot_channel, self.spot_channel_lbl, self.diameter_value, self.diameter_lbl, self.threshold_value, self.threshold_lbl, self.spot_viewer_btn]
963
+ for wg in self.spot_detection_widgets:
964
+ wg.setEnabled(False)
966
965
 
967
966
  def enable_spot_preview(self):
968
967
 
969
968
  diam = self.diameter_value.text().replace(',','').replace('.','')
970
969
  thresh = self.threshold_value.text().replace(',','').replace('.','')
971
970
  if diam.isnumeric() and thresh.isnumeric():
972
- self.preview_spot.setEnabled(True)
971
+ self.spot_viewer_btn.setEnabled(True)
973
972
  else:
974
- self.preview_spot.setEnabled(False)
973
+ self.spot_viewer_btn.setEnabled(False)
975
974
 
976
975
  def spot_preview(self):
977
976
  self.locate_image()
978
977
  if self.test_frame is not None:
979
978
  self.locate_mask()
980
979
  if self.test_mask is not None:
981
- self.spot_visual = ThresholdSpot(current_channel=self.spot_channel.currentIndex(), img=self.test_frame,
982
- mask=self.test_mask, parent_window=self)
980
+ self.spot_visual = SpotDetectionVisualizer(frame_slider=True,
981
+ contrast_slider=True,
982
+ cell_type=self.mode,
983
+ channel_cb=True,
984
+ channel_names = self.channel_names,
985
+ stack_path=self.current_stack,
986
+ n_channels=len(self.channel_names),
987
+ target_channel=self.spot_channel.currentIndex(),
988
+ window_title='Detect spots',
989
+ parent_channel_cb=self.spot_channel,
990
+ parent_diameter_le=self.diameter_value,
991
+ parent_threshold_le=self.threshold_value,
992
+ PxToUm = 1,)
993
+ self.spot_visual.show()
994
+ #self.spot_visual = ThresholdSpot(current_channel=self.spot_channel.currentIndex(), img=self.test_frame,
995
+ # mask=self.test_mask, parent_window=self)
983
996
 
984
997
  def enable_spot_detection(self):
985
- if self.spot_check.isChecked():
986
- self.spot_channel.setEnabled(True)
987
- self.spot_channel_lbl.setEnabled(True)
988
- self.diameter_value.setEnabled(True)
989
- self.diameter_lbl.setEnabled(True)
990
- self.threshold_value.setEnabled(True)
991
- self.threshold_lbl.setEnabled(True)
992
- self.preview_spot.setEnabled(True)
993
998
 
999
+ if self.spot_check.isChecked():
1000
+ for wg in self.spot_detection_widgets:
1001
+ wg.setEnabled(True)
994
1002
  else:
995
- self.spot_channel.setEnabled(False)
996
- self.spot_channel_lbl.setEnabled(False)
997
- self.diameter_value.setEnabled(False)
998
- self.diameter_lbl.setEnabled(False)
999
- self.threshold_value.setEnabled(False)
1000
- self.threshold_lbl.setEnabled(False)
1001
- self.preview_spot.setEnabled(False)
1003
+ for wg in self.spot_detection_widgets:
1004
+ wg.setEnabled(False)
@@ -96,7 +96,7 @@ class ConfigSignalPlot(QWidget, Styles):
96
96
  main_layout.addWidget(panel_title, alignment=Qt.AlignCenter)
97
97
 
98
98
  labels = [QLabel('population: '), QLabel('class: '), QLabel('time of\ninterest: '), QLabel('cmap: ')]
99
- self.cb_options = [['targets','effectors'],['class'], ['t0'], []]
99
+ self.cb_options = [['targets','effectors'],[], [], []]
100
100
  self.cbs = [QComboBox() for i in range(len(labels))]
101
101
  self.cbs[-1] = QColormapComboBox()
102
102
 
@@ -183,6 +183,11 @@ class ConfigSignalPlot(QWidget, Styles):
183
183
  self.auto_close = True
184
184
  return None
185
185
 
186
+ if 'class' in self.all_columns:
187
+ class_columns.append("class")
188
+ if 't0' in self.all_columns:
189
+ time_columns.append('t0')
190
+
186
191
  self.cbs[2].clear()
187
192
  self.cbs[2].addItems(np.unique(self.cb_options[2]+time_columns))
188
193
 
@@ -339,7 +344,7 @@ class ConfigSignalPlot(QWidget, Styles):
339
344
 
340
345
  for block,movie_group in self.df.groupby(['well','position']):
341
346
 
342
- well_signal_mean, well_std_mean, timeline_all, matrix_all = mean_signal(movie_group, self.feature_selected, class_col, time_col=time_col, class_value=[0,1], return_matrix=True, forced_max_duration=max_time)
347
+ well_signal_mean, well_std_mean, timeline_all, matrix_all = mean_signal(movie_group, self.feature_selected, class_col, time_col=time_col, class_value=None, return_matrix=True, forced_max_duration=max_time)
343
348
  well_signal_event, well_std_event, timeline_event, matrix_event = mean_signal(movie_group, self.feature_selected, class_col, time_col=time_col, class_value=[0], return_matrix=True, forced_max_duration=max_time)
344
349
  well_signal_no_event, well_std_no_event, timeline_no_event, matrix_no_event = mean_signal(movie_group, self.feature_selected, class_col, time_col=time_col, class_value=[1], return_matrix=True, forced_max_duration=max_time)
345
350
  self.mean_plots_timeline = timeline_all
@@ -354,7 +359,7 @@ class ConfigSignalPlot(QWidget, Styles):
354
359
  # Per well
355
360
  for well,well_group in self.df.groupby('well'):
356
361
 
357
- well_signal_mean, well_std_mean, timeline_all, matrix_all = mean_signal(well_group, self.feature_selected, class_col, time_col=time_col, class_value=[0,1], return_matrix=True, forced_max_duration=max_time)
362
+ well_signal_mean, well_std_mean, timeline_all, matrix_all = mean_signal(well_group, self.feature_selected, class_col, time_col=time_col, class_value=None, return_matrix=True, forced_max_duration=max_time)
358
363
  well_signal_event, well_std_event, timeline_event, matrix_event = mean_signal(well_group, self.feature_selected, class_col, time_col=time_col, class_value=[0], return_matrix=True, forced_max_duration=max_time)
359
364
  well_signal_no_event, well_std_no_event, timeline_no_event, matrix_no_event = mean_signal(well_group, self.feature_selected, class_col, time_col=time_col, class_value=[1], return_matrix=True, forced_max_duration=max_time)
360
365