celldetective 1.4.2__py3-none-any.whl → 1.5.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. celldetective/__init__.py +25 -0
  2. celldetective/__main__.py +62 -43
  3. celldetective/_version.py +1 -1
  4. celldetective/extra_properties.py +477 -399
  5. celldetective/filters.py +192 -97
  6. celldetective/gui/InitWindow.py +541 -411
  7. celldetective/gui/__init__.py +0 -15
  8. celldetective/gui/about.py +44 -39
  9. celldetective/gui/analyze_block.py +120 -84
  10. celldetective/gui/base/__init__.py +0 -0
  11. celldetective/gui/base/channel_norm_generator.py +335 -0
  12. celldetective/gui/base/components.py +249 -0
  13. celldetective/gui/base/feature_choice.py +92 -0
  14. celldetective/gui/base/figure_canvas.py +52 -0
  15. celldetective/gui/base/list_widget.py +133 -0
  16. celldetective/gui/{styles.py → base/styles.py} +92 -36
  17. celldetective/gui/base/utils.py +33 -0
  18. celldetective/gui/base_annotator.py +900 -767
  19. celldetective/gui/classifier_widget.py +6 -22
  20. celldetective/gui/configure_new_exp.py +777 -671
  21. celldetective/gui/control_panel.py +635 -524
  22. celldetective/gui/dynamic_progress.py +449 -0
  23. celldetective/gui/event_annotator.py +2023 -1662
  24. celldetective/gui/generic_signal_plot.py +1292 -944
  25. celldetective/gui/gui_utils.py +899 -1289
  26. celldetective/gui/interactions_block.py +658 -0
  27. celldetective/gui/interactive_timeseries_viewer.py +447 -0
  28. celldetective/gui/json_readers.py +48 -15
  29. celldetective/gui/layouts/__init__.py +5 -0
  30. celldetective/gui/layouts/background_model_free_layout.py +537 -0
  31. celldetective/gui/layouts/channel_offset_layout.py +134 -0
  32. celldetective/gui/layouts/local_correction_layout.py +91 -0
  33. celldetective/gui/layouts/model_fit_layout.py +372 -0
  34. celldetective/gui/layouts/operation_layout.py +68 -0
  35. celldetective/gui/layouts/protocol_designer_layout.py +96 -0
  36. celldetective/gui/pair_event_annotator.py +3130 -2435
  37. celldetective/gui/plot_measurements.py +586 -267
  38. celldetective/gui/plot_signals_ui.py +724 -506
  39. celldetective/gui/preprocessing_block.py +395 -0
  40. celldetective/gui/process_block.py +1678 -1831
  41. celldetective/gui/seg_model_loader.py +580 -473
  42. celldetective/gui/settings/__init__.py +0 -7
  43. celldetective/gui/settings/_cellpose_model_params.py +181 -0
  44. celldetective/gui/settings/_event_detection_model_params.py +95 -0
  45. celldetective/gui/settings/_segmentation_model_params.py +159 -0
  46. celldetective/gui/settings/_settings_base.py +77 -65
  47. celldetective/gui/settings/_settings_event_model_training.py +752 -526
  48. celldetective/gui/settings/_settings_measurements.py +1133 -964
  49. celldetective/gui/settings/_settings_neighborhood.py +574 -488
  50. celldetective/gui/settings/_settings_segmentation_model_training.py +779 -564
  51. celldetective/gui/settings/_settings_signal_annotator.py +329 -305
  52. celldetective/gui/settings/_settings_tracking.py +1304 -1094
  53. celldetective/gui/settings/_stardist_model_params.py +98 -0
  54. celldetective/gui/survival_ui.py +422 -312
  55. celldetective/gui/tableUI.py +1665 -1701
  56. celldetective/gui/table_ops/_maths.py +295 -0
  57. celldetective/gui/table_ops/_merge_groups.py +140 -0
  58. celldetective/gui/table_ops/_merge_one_hot.py +95 -0
  59. celldetective/gui/table_ops/_query_table.py +43 -0
  60. celldetective/gui/table_ops/_rename_col.py +44 -0
  61. celldetective/gui/thresholds_gui.py +382 -179
  62. celldetective/gui/viewers/__init__.py +0 -0
  63. celldetective/gui/viewers/base_viewer.py +700 -0
  64. celldetective/gui/viewers/channel_offset_viewer.py +331 -0
  65. celldetective/gui/viewers/contour_viewer.py +394 -0
  66. celldetective/gui/viewers/size_viewer.py +153 -0
  67. celldetective/gui/viewers/spot_detection_viewer.py +341 -0
  68. celldetective/gui/viewers/threshold_viewer.py +309 -0
  69. celldetective/gui/workers.py +304 -126
  70. celldetective/log_manager.py +92 -0
  71. celldetective/measure.py +1895 -1478
  72. celldetective/napari/__init__.py +0 -0
  73. celldetective/napari/utils.py +1025 -0
  74. celldetective/neighborhood.py +1914 -1448
  75. celldetective/preprocessing.py +1620 -1220
  76. celldetective/processes/__init__.py +0 -0
  77. celldetective/processes/background_correction.py +271 -0
  78. celldetective/processes/compute_neighborhood.py +894 -0
  79. celldetective/processes/detect_events.py +246 -0
  80. celldetective/processes/measure_cells.py +565 -0
  81. celldetective/processes/segment_cells.py +760 -0
  82. celldetective/processes/track_cells.py +435 -0
  83. celldetective/processes/train_segmentation_model.py +694 -0
  84. celldetective/processes/train_signal_model.py +265 -0
  85. celldetective/processes/unified_process.py +292 -0
  86. celldetective/regionprops/_regionprops.py +358 -317
  87. celldetective/relative_measurements.py +987 -710
  88. celldetective/scripts/measure_cells.py +313 -212
  89. celldetective/scripts/measure_relative.py +90 -46
  90. celldetective/scripts/segment_cells.py +165 -104
  91. celldetective/scripts/segment_cells_thresholds.py +96 -68
  92. celldetective/scripts/track_cells.py +198 -149
  93. celldetective/scripts/train_segmentation_model.py +324 -201
  94. celldetective/scripts/train_signal_model.py +87 -45
  95. celldetective/segmentation.py +844 -749
  96. celldetective/signals.py +3514 -2861
  97. celldetective/tracking.py +30 -15
  98. celldetective/utils/__init__.py +0 -0
  99. celldetective/utils/cellpose_utils/__init__.py +133 -0
  100. celldetective/utils/color_mappings.py +42 -0
  101. celldetective/utils/data_cleaning.py +630 -0
  102. celldetective/utils/data_loaders.py +450 -0
  103. celldetective/utils/dataset_helpers.py +207 -0
  104. celldetective/utils/downloaders.py +197 -0
  105. celldetective/utils/event_detection/__init__.py +8 -0
  106. celldetective/utils/experiment.py +1782 -0
  107. celldetective/utils/image_augmenters.py +308 -0
  108. celldetective/utils/image_cleaning.py +74 -0
  109. celldetective/utils/image_loaders.py +926 -0
  110. celldetective/utils/image_transforms.py +335 -0
  111. celldetective/utils/io.py +62 -0
  112. celldetective/utils/mask_cleaning.py +348 -0
  113. celldetective/utils/mask_transforms.py +5 -0
  114. celldetective/utils/masks.py +184 -0
  115. celldetective/utils/maths.py +351 -0
  116. celldetective/utils/model_getters.py +325 -0
  117. celldetective/utils/model_loaders.py +296 -0
  118. celldetective/utils/normalization.py +380 -0
  119. celldetective/utils/parsing.py +465 -0
  120. celldetective/utils/plots/__init__.py +0 -0
  121. celldetective/utils/plots/regression.py +53 -0
  122. celldetective/utils/resources.py +34 -0
  123. celldetective/utils/stardist_utils/__init__.py +104 -0
  124. celldetective/utils/stats.py +90 -0
  125. celldetective/utils/types.py +21 -0
  126. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/METADATA +1 -1
  127. celldetective-1.5.0b0.dist-info/RECORD +187 -0
  128. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/WHEEL +1 -1
  129. tests/gui/test_new_project.py +129 -117
  130. tests/gui/test_project.py +127 -79
  131. tests/test_filters.py +39 -15
  132. tests/test_notebooks.py +8 -0
  133. tests/test_tracking.py +232 -13
  134. tests/test_utils.py +123 -77
  135. celldetective/gui/base_components.py +0 -23
  136. celldetective/gui/layouts.py +0 -1602
  137. celldetective/gui/processes/compute_neighborhood.py +0 -594
  138. celldetective/gui/processes/measure_cells.py +0 -360
  139. celldetective/gui/processes/segment_cells.py +0 -499
  140. celldetective/gui/processes/track_cells.py +0 -303
  141. celldetective/gui/processes/train_segmentation_model.py +0 -270
  142. celldetective/gui/processes/train_signal_model.py +0 -108
  143. celldetective/gui/table_ops/merge_groups.py +0 -118
  144. celldetective/gui/viewers.py +0 -1354
  145. celldetective/io.py +0 -3663
  146. celldetective/utils.py +0 -3108
  147. celldetective-1.4.2.dist-info/RECORD +0 -123
  148. /celldetective/{gui/processes → processes}/downloader.py +0 -0
  149. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/entry_points.txt +0 -0
  150. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/licenses/LICENSE +0 -0
  151. {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/top_level.txt +0 -0
@@ -1,23 +1,41 @@
1
- from PyQt5.QtWidgets import QMessageBox, QScrollArea, QButtonGroup, QComboBox, \
2
- QCheckBox, QVBoxLayout, QLabel, QHBoxLayout, QPushButton, \
3
- QRadioButton, QSizePolicy
1
+ from PyQt5.QtWidgets import (
2
+ QMessageBox,
3
+ QScrollArea,
4
+ QButtonGroup,
5
+ QComboBox,
6
+ QCheckBox,
7
+ QVBoxLayout,
8
+ QLabel,
9
+ QHBoxLayout,
10
+ QPushButton,
11
+ QRadioButton,
12
+ QSizePolicy,
13
+ )
4
14
  from PyQt5.QtCore import Qt, QRect
5
15
  from PyQt5.QtGui import QDoubleValidator
6
16
 
7
- from celldetective.gui import CelldetectiveWidget
8
- from celldetective.gui.gui_utils import center_window, FigureCanvas
17
+ from celldetective.gui.base.components import CelldetectiveWidget
18
+ from celldetective.gui.base.figure_canvas import FigureCanvas
19
+ from celldetective.gui.base.utils import center_window
9
20
 
10
21
  from superqt.fonticon import icon
11
22
  from fonticon_mdi6 import MDI6
12
- from celldetective.utils import get_software_location, _extract_labels_from_config
13
- from celldetective.io import load_experiment_tables, get_experiment_antibodies, get_experiment_cell_types, get_experiment_concentrations, \
14
- get_positions_in_well, get_experiment_wells
23
+ from celldetective import get_software_location
24
+ from celldetective.utils.parsing import _extract_labels_from_config
25
+ from celldetective.utils.data_loaders import load_experiment_tables
26
+ from celldetective.utils.experiment import (
27
+ get_experiment_wells,
28
+ get_experiment_concentrations,
29
+ get_experiment_cell_types,
30
+ get_experiment_antibodies,
31
+ get_positions_in_well,
32
+ )
15
33
  import numpy as np
16
34
  import json
17
35
  import os
18
36
  import matplotlib.pyplot as plt
19
37
 
20
- plt.rcParams['svg.fonttype'] = 'none'
38
+ plt.rcParams["svg.fonttype"] = "none"
21
39
  from glob import glob
22
40
  import pandas as pd
23
41
  from matplotlib.cm import tab10
@@ -52,15 +70,21 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
52
70
  # sns.color_palette("cubehelix", as_cmap=True)
53
71
  # sns.color_palette("ch:s=-.2,r=.6", as_cmap=True)
54
72
 
55
- print('Parent wells: ', self.wells)
73
+ print("Parent wells: ", self.wells)
56
74
 
57
- self.well_option = self.parent_window.parent_window.well_list.getSelectedIndices()
58
- self.position_option = self.parent_window.parent_window.position_list.getSelectedIndices()
75
+ self.well_option = (
76
+ self.parent_window.parent_window.well_list.getSelectedIndices()
77
+ )
78
+ self.position_option = (
79
+ self.parent_window.parent_window.position_list.getSelectedIndices()
80
+ )
59
81
  self.interpret_pos_location()
60
82
  # self.load_available_tables()
61
83
  # self.config_path = self.exp_dir + self.config_name
62
84
 
63
- self.screen_height = self.parent_window.parent_window.parent_window.screen_height
85
+ self.screen_height = (
86
+ self.parent_window.parent_window.parent_window.screen_height
87
+ )
64
88
  center_window(self)
65
89
  # self.setMinimumHeight(int(0.8*self.screen_height))
66
90
  # self.setMaximumHeight(int(0.8*self.screen_height))
@@ -71,7 +95,6 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
71
95
  self.hue_colors = {0: self.palette[0], 1: self.palette[3]}
72
96
 
73
97
  def interpret_pos_location(self):
74
-
75
98
  """
76
99
  Read the well/position selection from the control panel to decide which data to load
77
100
  Set position_indices to None if all positions must be taken
@@ -89,7 +112,6 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
89
112
  self.position_indices = np.array([self.position_option], dtype=int)
90
113
 
91
114
  def populate_widget(self):
92
-
93
115
  """
94
116
  Create the multibox design.
95
117
 
@@ -99,15 +121,25 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
99
121
  main_layout = QVBoxLayout()
100
122
  self.setLayout(main_layout)
101
123
  main_layout.setContentsMargins(30, 30, 30, 30)
102
- panel_title = QLabel('Options')
103
- panel_title.setStyleSheet("""
124
+ panel_title = QLabel("Options")
125
+ panel_title.setStyleSheet(
126
+ """
104
127
  font-weight: bold;
105
128
  padding: 0px;
106
- """)
129
+ """
130
+ )
107
131
  main_layout.addWidget(panel_title, alignment=Qt.AlignCenter)
108
132
 
109
- labels = [QLabel('population: '), QLabel('class: '), QLabel('group: ')] # , QLabel('time of\ninterest: ')]
110
- self.cb_options = [self.parent_window.parent_window.populations, ['class'], ['group']] # , ['t0','first detection']]
133
+ labels = [
134
+ QLabel("population: "),
135
+ QLabel("class: "),
136
+ QLabel("group: "),
137
+ ] # , QLabel('time of\ninterest: ')]
138
+ self.cb_options = [
139
+ self.parent_window.parent_window.populations,
140
+ ["class"],
141
+ ["group"],
142
+ ] # , ['t0','first detection']]
111
143
  self.cbs = [QComboBox() for i in range(len(labels))]
112
144
  self.cbs[0].currentIndexChanged.connect(self.set_classes_and_times)
113
145
 
@@ -164,7 +196,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
164
196
  # #time_calib_layout.addWidget(QLabel(' min'))
165
197
  # main_layout.addLayout(time_calib_layout)
166
198
 
167
- self.submit_btn = QPushButton('Submit')
199
+ self.submit_btn = QPushButton("Submit")
168
200
  self.submit_btn.setStyleSheet(self.button_style_sheet)
169
201
  self.submit_btn.clicked.connect(self.process_signal)
170
202
  main_layout.addWidget(self.submit_btn)
@@ -189,31 +221,34 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
189
221
  self.cbs[2].setEnabled(False)
190
222
 
191
223
  def set_classes_and_times(self):
192
- ext = 'csv'
224
+ ext = "csv"
193
225
  # Look for all classes and times
194
- tables = glob(self.exp_dir + os.sep.join(['W*', '*', 'output', 'tables', f'trajectories_*{ext}']))
226
+ tables = glob(
227
+ self.exp_dir
228
+ + os.sep.join(["W*", "*", "output", "tables", f"trajectories_*{ext}"])
229
+ )
195
230
  self.all_columns = []
196
231
  for tab in tables:
197
232
  cols = pd.read_csv(tab, nrows=1).columns.tolist()
198
233
  self.all_columns.extend(cols)
199
234
  self.all_columns = np.unique(self.all_columns)
200
- class_idx = np.array([s.startswith('class_') for s in self.all_columns])
201
- group_idx = np.array([s.startswith('group_') for s in self.all_columns])
235
+ class_idx = np.array([s.startswith("class_") for s in self.all_columns])
236
+ group_idx = np.array([s.startswith("group_") for s in self.all_columns])
202
237
 
203
- print(f'{class_idx=} {group_idx=} {self.all_columns=}')
238
+ print(f"{class_idx=} {group_idx=} {self.all_columns=}")
204
239
  # time_idx = np.array([s.startswith('t_') for s in self.all_columns])
205
240
  try:
206
- if len(class_idx)>0:
241
+ if len(class_idx) > 0:
207
242
  class_columns = list(self.all_columns[class_idx])
208
243
  else:
209
244
  class_columns = []
210
- if len(group_idx)>0:
245
+ if len(group_idx) > 0:
211
246
  group_columns = list(self.all_columns[group_idx])
212
247
  else:
213
248
  group_columns = []
214
249
  # time_columns = list(self.all_columns[time_idx])
215
250
  except Exception as e:
216
- print(f'L210 columns not found {e}')
251
+ print(f"L210 columns not found {e}")
217
252
  self.auto_close = True
218
253
  return None
219
254
 
@@ -238,11 +273,11 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
238
273
  self.feature_cb = QComboBox()
239
274
  self.feature_cb.addItems(feats)
240
275
  hbox = QHBoxLayout()
241
- hbox.addWidget(QLabel('feature: '), 33)
276
+ hbox.addWidget(QLabel("feature: "), 33)
242
277
  hbox.addWidget(self.feature_cb, 66)
243
278
  layout.addLayout(hbox)
244
279
 
245
- self.set_feature_btn = QPushButton('set')
280
+ self.set_feature_btn = QPushButton("set")
246
281
  self.set_feature_btn.clicked.connect(self.compute_signals)
247
282
  layout.addWidget(self.set_feature_btn)
248
283
  self.feature_choice_widget.show()
@@ -261,7 +296,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
261
296
  self.feature_cb = QComboBox()
262
297
  self.feature_cb.addItems(feats)
263
298
  hbox = QHBoxLayout()
264
- hbox.addWidget(QLabel('feature: '), 33)
299
+ hbox.addWidget(QLabel("feature: "), 33)
265
300
  hbox.addWidget(self.feature_cb, 66)
266
301
  # hbox.addWidget((QLabel('Plot two features')))
267
302
  layout.addLayout(hbox)
@@ -282,7 +317,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
282
317
  # hbox_two.addWidget(self.feature_two_cb, 66)
283
318
  # layout.addLayout(hbox_two)
284
319
 
285
- self.set_feature_btn = QPushButton('set')
320
+ self.set_feature_btn = QPushButton("set")
286
321
  self.set_feature_btn.clicked.connect(self.compute_signals)
287
322
  layout.addWidget(self.set_feature_btn)
288
323
  self.feature_choice_widget.show()
@@ -306,32 +341,34 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
306
341
  self.survivalWidget = CelldetectiveWidget()
307
342
  self.scroll = QScrollArea()
308
343
  self.survivalWidget.setMinimumHeight(int(0.8 * self.screen_height))
309
- self.survivalWidget.setWindowTitle('signals')
344
+ self.survivalWidget.setWindowTitle("signals")
310
345
  self.plotvbox = QVBoxLayout(self.survivalWidget)
311
346
  self.plotvbox.setContentsMargins(30, 30, 30, 30)
312
- self.survival_title = QLabel('Signal function')
313
- self.survival_title.setStyleSheet("""
347
+ self.survival_title = QLabel("Signal function")
348
+ self.survival_title.setStyleSheet(
349
+ """
314
350
  font-weight: bold;
315
351
  padding: 0px;
316
- """)
352
+ """
353
+ )
317
354
  self.plotvbox.addWidget(self.survival_title, alignment=Qt.AlignCenter)
318
355
 
319
356
  plot_buttons_hbox = QHBoxLayout()
320
- plot_buttons_hbox.addWidget(QLabel(''), 80, alignment=Qt.AlignLeft)
357
+ plot_buttons_hbox.addWidget(QLabel(""), 80, alignment=Qt.AlignLeft)
321
358
 
322
- self.legend_btn = QPushButton('')
359
+ self.legend_btn = QPushButton("")
323
360
  self.legend_btn.setIcon(icon(MDI6.text_box, color="black"))
324
361
  self.legend_btn.setStyleSheet(self.button_select_all)
325
- self.legend_btn.setToolTip('Show or hide the legend')
362
+ self.legend_btn.setToolTip("Show or hide the legend")
326
363
  self.legend_visible = True
327
364
  self.legend_btn.clicked.connect(self.show_hide_legend)
328
365
  plot_buttons_hbox.addWidget(self.legend_btn, 5, alignment=Qt.AlignRight)
329
366
 
330
- self.log_btn = QPushButton('')
367
+ self.log_btn = QPushButton("")
331
368
  self.log_btn.setIcon(icon(MDI6.math_log, color="black"))
332
369
  self.log_btn.setStyleSheet(self.button_select_all)
333
370
  self.log_btn.clicked.connect(self.switch_to_log)
334
- self.log_btn.setToolTip('Enable or disable log scale')
371
+ self.log_btn.setToolTip("Enable or disable log scale")
335
372
  plot_buttons_hbox.addWidget(self.log_btn, 5, alignment=Qt.AlignRight)
336
373
 
337
374
  # self.ci_btn = QPushButton('')
@@ -341,11 +378,11 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
341
378
  # self.ci_btn.setToolTip('Show or hide confidence intervals.')
342
379
  # plot_buttons_hbox.addWidget(self.ci_btn, 5, alignment=Qt.AlignRight)
343
380
 
344
- self.cell_lines_btn = QPushButton('')
381
+ self.cell_lines_btn = QPushButton("")
345
382
  self.cell_lines_btn.setIcon(icon(MDI6.view_headline, color="black"))
346
383
  self.cell_lines_btn.setStyleSheet(self.button_select_all)
347
384
  self.cell_lines_btn.clicked.connect(self.switch_cell_lines)
348
- self.cell_lines_btn.setToolTip('Show or hide individual cell signals.')
385
+ self.cell_lines_btn.setToolTip("Show or hide individual cell signals.")
349
386
  plot_buttons_hbox.addWidget(self.cell_lines_btn, 5, alignment=Qt.AlignRight)
350
387
 
351
388
  self.fig, self.ax = plt.subplots(1, 1, figsize=(10, 10)) # ,figsize=(10,10)
@@ -356,22 +393,22 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
356
393
  self.initialize_axis()
357
394
  plt.tight_layout()
358
395
 
359
- self.fig.set_facecolor('none') # or 'None'
396
+ self.fig.set_facecolor("none") # or 'None'
360
397
  self.fig.canvas.setStyleSheet("background-color: transparent;")
361
398
  self.survival_window.canvas.draw()
362
399
 
363
400
  # self.survival_window.layout.addWidget(QLabel('WHAAAAATTT???'))
364
401
 
365
402
  self.plot_options = [QRadioButton() for i in range(3)]
366
- self.radio_labels = ['well', 'pos', 'both']
403
+ self.radio_labels = ["well", "pos", "both"]
367
404
  radio_hbox = QHBoxLayout()
368
- radio_hbox.setContentsMargins(30,30,30,30)
405
+ radio_hbox.setContentsMargins(30, 30, 30, 30)
369
406
  self.plot_btn_group = QButtonGroup()
370
407
  for i in range(3):
371
- self.plot_options[i].setText(self.radio_labels[i])
372
- #self.plot_options[i].toggled.connect(self.plot_survivals)
373
- self.plot_btn_group.addButton(self.plot_options[i])
374
- radio_hbox.addWidget(self.plot_options[i], 33, alignment=Qt.AlignCenter)
408
+ self.plot_options[i].setText(self.radio_labels[i])
409
+ # self.plot_options[i].toggled.connect(self.plot_survivals)
410
+ self.plot_btn_group.addButton(self.plot_options[i])
411
+ radio_hbox.addWidget(self.plot_options[i], 33, alignment=Qt.AlignCenter)
375
412
  self.plot_btn_group.buttonClicked[int].connect(self.plot_survivals)
376
413
 
377
414
  if self.position_indices is not None:
@@ -427,11 +464,13 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
427
464
  # class_selection_hbox.addWidget(self.no_event_btn, 33, alignment=Qt.AlignRight)
428
465
  # self.plotvbox.addLayout(class_selection_hbox)
429
466
 
430
- self.select_pos_label = QLabel('Select positions')
431
- self.select_pos_label.setStyleSheet("""
467
+ self.select_pos_label = QLabel("Select positions")
468
+ self.select_pos_label.setStyleSheet(
469
+ """
432
470
  font-weight: bold;
433
471
  padding: 0px;
434
- """)
472
+ """
473
+ )
435
474
  self.plotvbox.addWidget(self.select_pos_label, alignment=Qt.AlignCenter)
436
475
  #
437
476
  # self.select_option = [QRadioButton() for i in range(2)]
@@ -454,14 +493,14 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
454
493
  self.load_coordinates()
455
494
  self.plot_spatial_location()
456
495
  # self.plot_positions()
457
- self.ax_scatter.spines['top'].set_visible(False)
458
- self.ax_scatter.spines['right'].set_visible(False)
459
- self.ax_scatter.set_aspect('equal')
496
+ self.ax_scatter.spines["top"].set_visible(False)
497
+ self.ax_scatter.spines["right"].set_visible(False)
498
+ self.ax_scatter.set_aspect("equal")
460
499
  self.ax_scatter.set_xticks([])
461
500
  self.ax_scatter.set_yticks([])
462
501
  plt.tight_layout()
463
502
 
464
- self.fig_scatter.set_facecolor('none') # or 'None'
503
+ self.fig_scatter.set_facecolor("none") # or 'None'
465
504
  self.fig_scatter.canvas.setStyleSheet("background-color: transparent;")
466
505
  self.plotvbox.addWidget(self.position_scatter)
467
506
 
@@ -476,14 +515,16 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
476
515
  self.scroll.setWidget(self.survivalWidget)
477
516
 
478
517
  self.scroll.setMinimumHeight(int(0.8 * self.screen_height))
479
- self.survivalWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
518
+ self.survivalWidget.setSizePolicy(
519
+ QSizePolicy.Expanding, QSizePolicy.Expanding
520
+ )
480
521
  self.scroll.show()
481
522
 
482
523
  def process_signal(self):
483
524
 
484
- print('you clicked!!')
525
+ print("you clicked!!")
485
526
  # self.FrameToMin = float(self.time_calibration_le.text().replace(',','.'))
486
- print(self.FrameToMin, 'set')
527
+ print(self.FrameToMin, "set")
487
528
 
488
529
  # read instructions from combobox options
489
530
  self.load_available_tables()
@@ -494,51 +535,68 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
494
535
 
495
536
  def generate_pos_selection_widget(self):
496
537
 
497
- self.well_names = self.df['well_name'].unique()
538
+ self.well_names = self.df["well_name"].unique()
498
539
  self.pos_names = self.df_pos_info[
499
- 'pos_name'].unique() # pd.DataFrame(self.ks_estimators_per_position)['position_name'].unique()
500
- print(f'POSITION NAMES: ', self.pos_names)
540
+ "pos_name"
541
+ ].unique() # pd.DataFrame(self.ks_estimators_per_position)['position_name'].unique()
542
+ print(f"POSITION NAMES: ", self.pos_names)
501
543
  self.usable_well_labels = []
502
544
  for name in self.well_names:
503
545
  for lbl in self.well_labels:
504
- if name + ':' in lbl:
546
+ if name + ":" in lbl:
505
547
  self.usable_well_labels.append(lbl)
506
548
 
507
549
  self.line_choice_widget = CelldetectiveWidget()
508
550
  self.line_check_vbox = QVBoxLayout()
509
551
  self.line_choice_widget.setLayout(self.line_check_vbox)
510
552
  if len(self.well_indices) > 1:
511
- self.well_display_options = [QCheckBox(self.usable_well_labels[i]) for i in
512
- range(len(self.usable_well_labels))]
553
+ self.well_display_options = [
554
+ QCheckBox(self.usable_well_labels[i])
555
+ for i in range(len(self.usable_well_labels))
556
+ ]
513
557
  for i in range(len(self.well_names)):
514
- self.line_check_vbox.addWidget(self.well_display_options[i], alignment=Qt.AlignLeft)
558
+ self.line_check_vbox.addWidget(
559
+ self.well_display_options[i], alignment=Qt.AlignLeft
560
+ )
515
561
  self.well_display_options[i].setChecked(True)
516
562
  self.well_display_options[i].toggled.connect(self.select_survival_lines)
517
563
  else:
518
- self.pos_display_options = [QCheckBox(self.pos_names[i]) for i in range(len(self.pos_names))]
564
+ self.pos_display_options = [
565
+ QCheckBox(self.pos_names[i]) for i in range(len(self.pos_names))
566
+ ]
519
567
  for i in range(len(self.pos_names)):
520
- self.line_check_vbox.addWidget(self.pos_display_options[i], alignment=Qt.AlignLeft)
568
+ self.line_check_vbox.addWidget(
569
+ self.pos_display_options[i], alignment=Qt.AlignLeft
570
+ )
521
571
  self.pos_display_options[i].setChecked(True)
522
572
  self.pos_display_options[i].toggled.connect(self.select_survival_lines)
523
573
 
524
574
  self.plotvbox.addWidget(self.line_choice_widget, alignment=Qt.AlignCenter)
525
575
 
526
576
  def load_available_tables(self):
527
-
528
577
  """
529
578
  Load the tables of the selected wells/positions from the control Panel for the population of interest
530
579
 
531
580
  """
532
581
 
533
- self.well_option = self.parent_window.parent_window.well_list.getSelectedIndices()
534
- self.position_option = self.parent_window.parent_window.position_list.getSelectedIndices()
535
-
536
- self.df, self.df_pos_info = load_experiment_tables(self.exp_dir, well_option=self.well_option, position_option=self.position_option,
537
- population=self.cbs[0].currentText(), return_pos_info=True)
582
+ self.well_option = (
583
+ self.parent_window.parent_window.well_list.getSelectedIndices()
584
+ )
585
+ self.position_option = (
586
+ self.parent_window.parent_window.position_list.getSelectedIndices()
587
+ )
588
+
589
+ self.df, self.df_pos_info = load_experiment_tables(
590
+ self.exp_dir,
591
+ well_option=self.well_option,
592
+ position_option=self.position_option,
593
+ population=self.cbs[0].currentText(),
594
+ return_pos_info=True,
595
+ )
538
596
 
539
597
  if self.df is None:
540
598
 
541
- print('No table could be found...')
599
+ print("No table could be found...")
542
600
  msgBox = QMessageBox()
543
601
  msgBox.setIcon(QMessageBox.Warning)
544
602
  msgBox.setText("No table could be found to compute survival...")
@@ -552,21 +610,25 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
552
610
  self.close()
553
611
  return None
554
612
  else:
555
- self.df_well_info = self.df_pos_info.loc[:,
556
- ['well_path', 'well_index', 'well_name', 'well_number', 'well_alias']].drop_duplicates()
613
+ self.df_well_info = self.df_pos_info.loc[
614
+ :, ["well_path", "well_index", "well_name", "well_number", "well_alias"]
615
+ ].drop_duplicates()
557
616
 
558
617
  def compute_signal_functions(self):
559
618
  wells = get_experiment_wells(self.exp_dir)
560
619
  antibodies = get_experiment_antibodies(self.exp_dir)
561
620
  cell_types = get_experiment_cell_types(self.exp_dir)
562
621
  concentrations = get_experiment_concentrations(self.exp_dir)
563
- well_name = [' '.join([s1, '+', s2, s3, 'pM']) for s1, s2, s3 in zip(cell_types, antibodies, concentrations)]
622
+ well_name = [
623
+ " ".join([s1, "+", s2, s3, "pM"])
624
+ for s1, s2, s3 in zip(cell_types, antibodies, concentrations)
625
+ ]
564
626
 
565
627
  data = []
566
628
  full_data = []
567
629
  print(self.well_option)
568
630
  if self.well_option > 1:
569
- self.plot_mode = 'wells'
631
+ self.plot_mode = "wells"
570
632
  for z, well in enumerate(wells): # loop over wells
571
633
  # print(well)
572
634
  if z not in self.well_indices:
@@ -576,80 +638,114 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
576
638
  for ind, pos in enumerate(positions): # loop over positions
577
639
  if self.position_indices is not None:
578
640
  if ind + 1 in self.position_indices:
579
- print(f'Processing position {pos}...')
641
+ print(f"Processing position {pos}...")
580
642
  tab_tc = pos + os.sep.join(
581
- ['output', 'tables', f'trajectories_{self.cbs[0].currentText()}.csv'])
643
+ [
644
+ "output",
645
+ "tables",
646
+ f"trajectories_{self.cbs[0].currentText()}.csv",
647
+ ]
648
+ )
582
649
  if not os.path.exists(tab_tc):
583
650
  return None
584
651
  else:
585
652
  data = pd.read_csv(tab_tc)
586
- data['well_name'] = well_name[z]
653
+ data["well_name"] = well_name[z]
587
654
  full_data.append(data)
588
655
 
589
656
  else:
590
- print(f'Processing position {pos}...')
657
+ print(f"Processing position {pos}...")
591
658
  tab_tc = pos + os.sep.join(
592
- ['output', 'tables', f'trajectories_{self.cbs[0].currentText()}.csv'])
659
+ [
660
+ "output",
661
+ "tables",
662
+ f"trajectories_{self.cbs[0].currentText()}.csv",
663
+ ]
664
+ )
593
665
  if not os.path.exists(tab_tc):
594
666
  return None
595
667
  else:
596
668
  data = pd.read_csv(tab_tc)
597
- data['well_name'] = well_name[z]
669
+ data["well_name"] = well_name[z]
598
670
  full_data.append(data)
599
671
  else:
600
- self.plot_mode = 'positions'
672
+ self.plot_mode = "positions"
601
673
  positions = get_positions_in_well(wells[self.well_indices[0]])
602
674
  for ind, pos in enumerate(positions): # loop over positions
603
675
  pos_name = pos.split(os.sep)[-2]
604
676
  if self.position_indices is not None:
605
677
  if ind + 1 in self.position_indices:
606
- print(f'Processing position {pos}...')
678
+ print(f"Processing position {pos}...")
607
679
  tab_tc = pos + os.sep.join(
608
- ['output', 'tables', f'trajectories_{self.cbs[0].currentText()}.csv'])
680
+ [
681
+ "output",
682
+ "tables",
683
+ f"trajectories_{self.cbs[0].currentText()}.csv",
684
+ ]
685
+ )
609
686
  if not os.path.exists(tab_tc):
610
687
  return None
611
688
  else:
612
689
  data = pd.read_csv(tab_tc)
613
- data['position'] = pos_name
690
+ data["position"] = pos_name
614
691
  full_data.append(data)
615
692
  else:
616
- print(f'Processing position {pos}...')
617
- tab_tc = pos + os.sep.join(['output', 'tables', f'trajectories_{self.cbs[0].currentText()}.csv'])
693
+ print(f"Processing position {pos}...")
694
+ tab_tc = pos + os.sep.join(
695
+ [
696
+ "output",
697
+ "tables",
698
+ f"trajectories_{self.cbs[0].currentText()}.csv",
699
+ ]
700
+ )
618
701
  if not os.path.exists(tab_tc):
619
702
  return None
620
703
  else:
621
704
  data = pd.read_csv(tab_tc)
622
- data['position'] = pos_name
705
+ data["position"] = pos_name
623
706
  full_data.append(data)
624
707
  self.plot_data = pd.concat(full_data, ignore_index=True)
625
708
 
626
- def generate_synchronized_matrix(self, well_group, feature_selected, cclass, max_time):
709
+ def generate_synchronized_matrix(
710
+ self, well_group, feature_selected, cclass, max_time
711
+ ):
627
712
 
628
713
  if isinstance(cclass, int):
629
714
  cclass = [cclass]
630
715
 
631
- n_cells = len(well_group.groupby(['position', 'TRACK_ID']))
716
+ n_cells = len(well_group.groupby(["position", "TRACK_ID"]))
632
717
  depth = int(2 * max_time + 3)
633
718
  matrix = np.zeros((n_cells, depth))
634
719
  matrix[:, :] = np.nan
635
720
  mapping = np.arange(-max_time - 1, max_time + 2)
636
721
  cid = 0
637
- for block, movie_group in well_group.groupby('position'):
638
- for tid, track_group in movie_group.loc[movie_group[self.cbs[1].currentText()].isin(cclass)].groupby(
639
- 'TRACK_ID'):
722
+ for block, movie_group in well_group.groupby("position"):
723
+ for tid, track_group in movie_group.loc[
724
+ movie_group[self.cbs[1].currentText()].isin(cclass)
725
+ ].groupby("TRACK_ID"):
640
726
  try:
641
- timeline = track_group['FRAME'].to_numpy().astype(int)
727
+ timeline = track_group["FRAME"].to_numpy().astype(int)
642
728
  feature = track_group[feature_selected].to_numpy()
643
729
  if self.checkBox_feature.isChecked():
644
- second_feature = track_group[self.second_feature_selected].to_numpy()
645
- if self.cbs[2].currentText().startswith('t') and not self.abs_time_checkbox.isChecked():
646
- t0 = math.floor(track_group[self.cbs[2].currentText()].to_numpy()[0])
730
+ second_feature = track_group[
731
+ self.second_feature_selected
732
+ ].to_numpy()
733
+ if (
734
+ self.cbs[2].currentText().startswith("t")
735
+ and not self.abs_time_checkbox.isChecked()
736
+ ):
737
+ t0 = math.floor(
738
+ track_group[self.cbs[2].currentText()].to_numpy()[0]
739
+ )
647
740
  timeline -= t0
648
- elif self.cbs[2].currentText() == 'first detection' and not self.abs_time_checkbox.isChecked():
649
-
650
- if 'area' in list(track_group.columns):
651
- print('area in list')
652
- feat = track_group['area'].values
741
+ elif (
742
+ self.cbs[2].currentText() == "first detection"
743
+ and not self.abs_time_checkbox.isChecked()
744
+ ):
745
+
746
+ if "area" in list(track_group.columns):
747
+ print("area in list")
748
+ feat = track_group["area"].values
653
749
  else:
654
750
  feat = feature
655
751
 
@@ -687,146 +783,318 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
687
783
  return mean_line, std_line
688
784
 
689
785
  def initialize_axis(self):
690
- plt.rcParams['svg.fonttype'] = 'none'
786
+ plt.rcParams["svg.fonttype"] = "none"
691
787
  plt.rcParams["font.family"] = "sans-serif"
692
788
  SMALL_SIZE = 5
693
789
  MEDIUM_SIZE = 6
694
790
  BIGGER_SIZE = 7
695
791
 
696
- plt.rc('font', size=SMALL_SIZE) # controls default text sizes
697
- plt.rc('axes', titlesize=SMALL_SIZE) # fontsize of the axes title
698
- plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
699
- plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels
700
- plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels
701
- plt.rc('legend', fontsize=SMALL_SIZE) # legend fontsize
702
- plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title
792
+ plt.rc("font", size=SMALL_SIZE) # controls default text sizes
793
+ plt.rc("axes", titlesize=SMALL_SIZE) # fontsize of the axes title
794
+ plt.rc("axes", labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
795
+ plt.rc("xtick", labelsize=SMALL_SIZE) # fontsize of the tick labels
796
+ plt.rc("ytick", labelsize=SMALL_SIZE) # fontsize of the tick labels
797
+ plt.rc("legend", fontsize=SMALL_SIZE) # legend fontsize
798
+ plt.rc("figure", titlesize=BIGGER_SIZE) # fontsize of the figure title
703
799
 
704
800
  fig, ax = plt.subplots(1, 1, figsize=(10, 5))
705
801
  if self.well_option > 1:
706
802
  if self.check_class.isChecked():
707
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
708
- hue=self.cbs[1].currentText(),
709
- dodge=True, palette=self.palette)
803
+ sns.boxenplot(
804
+ ax=self.ax,
805
+ data=self.plot_data,
806
+ y=self.feature_selected,
807
+ x="well_name",
808
+ hue=self.cbs[1].currentText(),
809
+ dodge=True,
810
+ palette=self.palette,
811
+ )
710
812
  if self.show_cell_lines:
711
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
712
- hue=self.cbs[1].currentText(),
713
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.palette)
813
+ sns.stripplot(
814
+ ax=self.ax,
815
+ data=self.plot_data,
816
+ y=self.feature_selected,
817
+ x="well_name",
818
+ hue=self.cbs[1].currentText(),
819
+ dodge=True,
820
+ alpha=0.3,
821
+ linewidth=0.5,
822
+ size=3,
823
+ palette=self.palette,
824
+ )
714
825
  elif self.check_group.isChecked():
715
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
716
- hue=self.cbs[2].currentText(),
717
- dodge=True, palette=self.hue_colors)
826
+ sns.boxenplot(
827
+ ax=self.ax,
828
+ data=self.plot_data,
829
+ y=self.feature_selected,
830
+ x="well_name",
831
+ hue=self.cbs[2].currentText(),
832
+ dodge=True,
833
+ palette=self.hue_colors,
834
+ )
718
835
  if self.show_cell_lines:
719
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
720
- hue=self.cbs[2].currentText(),
721
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.hue_colors)
836
+ sns.stripplot(
837
+ ax=self.ax,
838
+ data=self.plot_data,
839
+ y=self.feature_selected,
840
+ x="well_name",
841
+ hue=self.cbs[2].currentText(),
842
+ dodge=True,
843
+ alpha=0.3,
844
+ linewidth=0.5,
845
+ size=3,
846
+ palette=self.hue_colors,
847
+ )
722
848
  else:
723
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
724
- color=self.palette[0],
725
- dodge=True)
849
+ sns.boxenplot(
850
+ ax=self.ax,
851
+ data=self.plot_data,
852
+ y=self.feature_selected,
853
+ x="well_name",
854
+ color=self.palette[0],
855
+ dodge=True,
856
+ )
726
857
  if self.show_cell_lines:
727
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
728
- color=self.palette[0],
729
- dodge=True, alpha=0.3, linewidth=0.5, size=3)
858
+ sns.stripplot(
859
+ ax=self.ax,
860
+ data=self.plot_data,
861
+ y=self.feature_selected,
862
+ x="well_name",
863
+ color=self.palette[0],
864
+ dodge=True,
865
+ alpha=0.3,
866
+ linewidth=0.5,
867
+ size=3,
868
+ )
730
869
  else:
731
870
  if self.check_class.isChecked():
732
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
733
- hue=self.cbs[1].currentText(),
734
- dodge=True, palette=self.palette)
871
+ sns.boxenplot(
872
+ ax=self.ax,
873
+ data=self.plot_data,
874
+ y=self.feature_selected,
875
+ x="position",
876
+ hue=self.cbs[1].currentText(),
877
+ dodge=True,
878
+ palette=self.palette,
879
+ )
735
880
  if self.show_cell_lines:
736
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
737
- hue=self.cbs[1].currentText(),
738
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.palette)
881
+ sns.stripplot(
882
+ ax=self.ax,
883
+ data=self.plot_data,
884
+ y=self.feature_selected,
885
+ x="position",
886
+ hue=self.cbs[1].currentText(),
887
+ dodge=True,
888
+ alpha=0.3,
889
+ linewidth=0.5,
890
+ size=3,
891
+ palette=self.palette,
892
+ )
739
893
  elif self.check_group.isChecked():
740
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
741
- hue=self.cbs[2].currentText(),
742
- dodge=True, palette=self.hue_colors)
894
+ sns.boxenplot(
895
+ ax=self.ax,
896
+ data=self.plot_data,
897
+ y=self.feature_selected,
898
+ x="position",
899
+ hue=self.cbs[2].currentText(),
900
+ dodge=True,
901
+ palette=self.hue_colors,
902
+ )
743
903
  if self.show_cell_lines:
744
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
745
- hue=self.cbs[2].currentText(),
746
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.hue_colors)
904
+ sns.stripplot(
905
+ ax=self.ax,
906
+ data=self.plot_data,
907
+ y=self.feature_selected,
908
+ x="position",
909
+ hue=self.cbs[2].currentText(),
910
+ dodge=True,
911
+ alpha=0.3,
912
+ linewidth=0.5,
913
+ size=3,
914
+ palette=self.hue_colors,
915
+ )
747
916
  else:
748
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
749
- color=self.palette[0],
750
- dodge=True)
917
+ sns.boxenplot(
918
+ ax=self.ax,
919
+ data=self.plot_data,
920
+ y=self.feature_selected,
921
+ x="position",
922
+ color=self.palette[0],
923
+ dodge=True,
924
+ )
751
925
  if self.show_cell_lines:
752
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
753
- color=self.palette[0],
754
- dodge=True, alpha=0.3, linewidth=0.5, size=3)
755
- self.ax.spines['top'].set_visible(False)
756
- self.ax.spines['right'].set_visible(False)
926
+ sns.stripplot(
927
+ ax=self.ax,
928
+ data=self.plot_data,
929
+ y=self.feature_selected,
930
+ x="position",
931
+ color=self.palette[0],
932
+ dodge=True,
933
+ alpha=0.3,
934
+ linewidth=0.5,
935
+ size=3,
936
+ )
937
+ self.ax.spines["top"].set_visible(False)
938
+ self.ax.spines["right"].set_visible(False)
757
939
  self.ax.set_ylabel(self.feature_selected)
758
940
  # ax.set_ylim(0.95,1.3)
759
941
  plt.tight_layout()
760
942
 
761
943
  def plot_survivals(self, id):
762
944
  self.ax.clear()
763
- plt.rcParams['svg.fonttype'] = 'none'
945
+ plt.rcParams["svg.fonttype"] = "none"
764
946
  plt.rcParams["font.family"] = "sans-serif"
765
947
  SMALL_SIZE = 5
766
948
  MEDIUM_SIZE = 6
767
949
  BIGGER_SIZE = 7
768
950
 
769
- plt.rc('font', size=SMALL_SIZE) # controls default text sizes
770
- plt.rc('axes', titlesize=SMALL_SIZE) # fontsize of the axes title
771
- plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
772
- plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels
773
- plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels
774
- plt.rc('legend', fontsize=SMALL_SIZE) # legend fontsize
775
- plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title
951
+ plt.rc("font", size=SMALL_SIZE) # controls default text sizes
952
+ plt.rc("axes", titlesize=SMALL_SIZE) # fontsize of the axes title
953
+ plt.rc("axes", labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
954
+ plt.rc("xtick", labelsize=SMALL_SIZE) # fontsize of the tick labels
955
+ plt.rc("ytick", labelsize=SMALL_SIZE) # fontsize of the tick labels
956
+ plt.rc("legend", fontsize=SMALL_SIZE) # legend fontsize
957
+ plt.rc("figure", titlesize=BIGGER_SIZE) # fontsize of the figure title
776
958
 
777
959
  fig, ax = plt.subplots(1, 1, figsize=(10, 5))
778
960
  if self.well_option > 1:
779
961
  if self.check_class.isChecked():
780
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
781
- hue=self.cbs[1].currentText(),
782
- dodge=True, palette=self.palette)
962
+ sns.boxenplot(
963
+ ax=self.ax,
964
+ data=self.plot_data,
965
+ y=self.feature_selected,
966
+ x="well_name",
967
+ hue=self.cbs[1].currentText(),
968
+ dodge=True,
969
+ palette=self.palette,
970
+ )
783
971
  if self.show_cell_lines:
784
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
785
- hue=self.cbs[1].currentText(),
786
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.palette)
972
+ sns.stripplot(
973
+ ax=self.ax,
974
+ data=self.plot_data,
975
+ y=self.feature_selected,
976
+ x="well_name",
977
+ hue=self.cbs[1].currentText(),
978
+ dodge=True,
979
+ alpha=0.3,
980
+ linewidth=0.5,
981
+ size=3,
982
+ palette=self.palette,
983
+ )
787
984
  elif self.check_group.isChecked():
788
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
789
- hue=self.cbs[2].currentText(),
790
- dodge=True, palette=self.hue_colors)
985
+ sns.boxenplot(
986
+ ax=self.ax,
987
+ data=self.plot_data,
988
+ y=self.feature_selected,
989
+ x="well_name",
990
+ hue=self.cbs[2].currentText(),
991
+ dodge=True,
992
+ palette=self.hue_colors,
993
+ )
791
994
  if self.show_cell_lines:
792
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
793
- hue=self.cbs[2].currentText(),
794
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.hue_colors)
995
+ sns.stripplot(
996
+ ax=self.ax,
997
+ data=self.plot_data,
998
+ y=self.feature_selected,
999
+ x="well_name",
1000
+ hue=self.cbs[2].currentText(),
1001
+ dodge=True,
1002
+ alpha=0.3,
1003
+ linewidth=0.5,
1004
+ size=3,
1005
+ palette=self.hue_colors,
1006
+ )
795
1007
  else:
796
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
797
- color=self.palette[0],
798
- dodge=True)
1008
+ sns.boxenplot(
1009
+ ax=self.ax,
1010
+ data=self.plot_data,
1011
+ y=self.feature_selected,
1012
+ x="well_name",
1013
+ color=self.palette[0],
1014
+ dodge=True,
1015
+ )
799
1016
  if self.show_cell_lines:
800
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='well_name',
801
- color=self.palette[0],
802
- dodge=True, alpha=0.3, linewidth=0.5, size=3)
1017
+ sns.stripplot(
1018
+ ax=self.ax,
1019
+ data=self.plot_data,
1020
+ y=self.feature_selected,
1021
+ x="well_name",
1022
+ color=self.palette[0],
1023
+ dodge=True,
1024
+ alpha=0.3,
1025
+ linewidth=0.5,
1026
+ size=3,
1027
+ )
803
1028
  else:
804
1029
  if self.check_class.isChecked():
805
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
806
- hue=self.cbs[1].currentText(),
807
- dodge=True, palette=self.palette)
1030
+ sns.boxenplot(
1031
+ ax=self.ax,
1032
+ data=self.plot_data,
1033
+ y=self.feature_selected,
1034
+ x="position",
1035
+ hue=self.cbs[1].currentText(),
1036
+ dodge=True,
1037
+ palette=self.palette,
1038
+ )
808
1039
  if self.show_cell_lines:
809
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
810
- hue=self.cbs[1].currentText(),
811
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.palette)
1040
+ sns.stripplot(
1041
+ ax=self.ax,
1042
+ data=self.plot_data,
1043
+ y=self.feature_selected,
1044
+ x="position",
1045
+ hue=self.cbs[1].currentText(),
1046
+ dodge=True,
1047
+ alpha=0.3,
1048
+ linewidth=0.5,
1049
+ size=3,
1050
+ palette=self.palette,
1051
+ )
812
1052
  elif self.check_group.isChecked():
813
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
814
- hue=self.cbs[2].currentText(),
815
- dodge=True, palette=self.hue_colors)
1053
+ sns.boxenplot(
1054
+ ax=self.ax,
1055
+ data=self.plot_data,
1056
+ y=self.feature_selected,
1057
+ x="position",
1058
+ hue=self.cbs[2].currentText(),
1059
+ dodge=True,
1060
+ palette=self.hue_colors,
1061
+ )
816
1062
  if self.show_cell_lines:
817
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
818
- hue=self.cbs[2].currentText(),
819
- dodge=True, alpha=0.3, linewidth=0.5, size=3, palette=self.hue_colors)
1063
+ sns.stripplot(
1064
+ ax=self.ax,
1065
+ data=self.plot_data,
1066
+ y=self.feature_selected,
1067
+ x="position",
1068
+ hue=self.cbs[2].currentText(),
1069
+ dodge=True,
1070
+ alpha=0.3,
1071
+ linewidth=0.5,
1072
+ size=3,
1073
+ palette=self.hue_colors,
1074
+ )
820
1075
  else:
821
- sns.boxenplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
822
- color=self.palette[0],
823
- dodge=True)
1076
+ sns.boxenplot(
1077
+ ax=self.ax,
1078
+ data=self.plot_data,
1079
+ y=self.feature_selected,
1080
+ x="position",
1081
+ color=self.palette[0],
1082
+ dodge=True,
1083
+ )
824
1084
  if self.show_cell_lines:
825
- sns.stripplot(ax=self.ax, data=self.plot_data, y=self.feature_selected, x='position',
826
- color=self.palette[0],
827
- dodge=True, alpha=0.3, linewidth=0.5, size=3)
828
- ax.spines['top'].set_visible(False)
829
- ax.spines['right'].set_visible(False)
1085
+ sns.stripplot(
1086
+ ax=self.ax,
1087
+ data=self.plot_data,
1088
+ y=self.feature_selected,
1089
+ x="position",
1090
+ color=self.palette[0],
1091
+ dodge=True,
1092
+ alpha=0.3,
1093
+ linewidth=0.5,
1094
+ size=3,
1095
+ )
1096
+ ax.spines["top"].set_visible(False)
1097
+ ax.spines["right"].set_visible(False)
830
1098
  ax.set_ylabel(self.feature_selected)
831
1099
  plt.tight_layout()
832
1100
  self.survival_window.setMinimumHeight(int(0.5 * self.screen_height))
@@ -835,53 +1103,84 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
835
1103
 
836
1104
  self.survival_window.canvas.draw()
837
1105
 
838
- def plot_line(self, line, color, label, mean_signal, ci_option=True, cell_lines_option=False, alpha_ci=0.5,
839
- alpha_cell_lines=0.5, std_signal=None, matrix=None):
1106
+ def plot_line(
1107
+ self,
1108
+ line,
1109
+ color,
1110
+ label,
1111
+ mean_signal,
1112
+ ci_option=True,
1113
+ cell_lines_option=False,
1114
+ alpha_ci=0.5,
1115
+ alpha_cell_lines=0.5,
1116
+ std_signal=None,
1117
+ matrix=None,
1118
+ ):
840
1119
  try:
841
- if 'second' in str(mean_signal):
842
- self.ax2.plot(line['timeline'] * self.FrameToMin, line[mean_signal], color=color, label=label)
1120
+ if "second" in str(mean_signal):
1121
+ self.ax2.plot(
1122
+ line["timeline"] * self.FrameToMin,
1123
+ line[mean_signal],
1124
+ color=color,
1125
+ label=label,
1126
+ )
843
1127
  else:
844
- self.ax.plot(line['timeline'] * self.FrameToMin, line[mean_signal], color=color, label=label)
1128
+ self.ax.plot(
1129
+ line["timeline"] * self.FrameToMin,
1130
+ line[mean_signal],
1131
+ color=color,
1132
+ label=label,
1133
+ )
845
1134
  if ci_option and std_signal is not None:
846
- if 'second' in str(mean_signal):
847
- self.ax2.fill_between(line['timeline'] * self.FrameToMin,
848
- [a - b for a, b in zip(line[mean_signal], line[std_signal])],
849
- [a + b for a, b in zip(line[mean_signal], line[std_signal])],
850
- color=color,
851
- alpha=alpha_ci,
852
- )
1135
+ if "second" in str(mean_signal):
1136
+ self.ax2.fill_between(
1137
+ line["timeline"] * self.FrameToMin,
1138
+ [a - b for a, b in zip(line[mean_signal], line[std_signal])],
1139
+ [a + b for a, b in zip(line[mean_signal], line[std_signal])],
1140
+ color=color,
1141
+ alpha=alpha_ci,
1142
+ )
853
1143
  else:
854
- self.ax.fill_between(line['timeline'] * self.FrameToMin,
855
- [a - b for a, b in zip(line[mean_signal], line[std_signal])],
856
- [a + b for a, b in zip(line[mean_signal], line[std_signal])],
857
- color=color,
858
- alpha=alpha_ci,
859
- )
1144
+ self.ax.fill_between(
1145
+ line["timeline"] * self.FrameToMin,
1146
+ [a - b for a, b in zip(line[mean_signal], line[std_signal])],
1147
+ [a + b for a, b in zip(line[mean_signal], line[std_signal])],
1148
+ color=color,
1149
+ alpha=alpha_ci,
1150
+ )
860
1151
  if cell_lines_option and matrix is not None:
861
1152
  print(mean_signal)
862
1153
  mat = line[matrix]
863
- if 'second' in str(mean_signal):
1154
+ if "second" in str(mean_signal):
864
1155
  for i in range(mat.shape[0]):
865
- self.ax2.plot(line['timeline'] * self.FrameToMin, mat[i, :], color=color,
866
- alpha=alpha_cell_lines)
1156
+ self.ax2.plot(
1157
+ line["timeline"] * self.FrameToMin,
1158
+ mat[i, :],
1159
+ color=color,
1160
+ alpha=alpha_cell_lines,
1161
+ )
867
1162
  else:
868
1163
  for i in range(mat.shape[0]):
869
- self.ax.plot(line['timeline'] * self.FrameToMin, mat[i, :], color=color, alpha=alpha_cell_lines)
1164
+ self.ax.plot(
1165
+ line["timeline"] * self.FrameToMin,
1166
+ mat[i, :],
1167
+ color=color,
1168
+ alpha=alpha_cell_lines,
1169
+ )
870
1170
 
871
1171
  except Exception as e:
872
- print(f'Exception {e}')
1172
+ print(f"Exception {e}")
873
1173
 
874
1174
  def switch_to_log(self):
875
-
876
1175
  """
877
1176
  Switch threshold histogram to log scale. Auto adjust.
878
1177
  """
879
1178
 
880
- if self.ax.get_yscale() == 'linear':
881
- self.ax.set_yscale('log')
1179
+ if self.ax.get_yscale() == "linear":
1180
+ self.ax.set_yscale("log")
882
1181
  # self.ax.set_ylim(0.01,1.05)
883
1182
  else:
884
- self.ax.set_yscale('linear')
1183
+ self.ax.set_yscale("linear")
885
1184
  # self.ax.set_ylim(0.01,1.05)
886
1185
 
887
1186
  # self.ax.autoscale()
@@ -902,20 +1201,22 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
902
1201
  def look_for_metadata(self):
903
1202
 
904
1203
  self.metadata_found = False
905
- self.metafiles = glob(self.exp_dir + os.sep.join([f'W*', '*', 'movie', '*metadata.txt'])) \
906
- + glob(self.exp_dir + os.sep.join([f'W*', '*', '*metadata.txt'])) \
907
- + glob(self.exp_dir + os.sep.join([f'W*', '*metadata.txt'])) \
908
- + glob(self.exp_dir + '*metadata.txt')
909
- print(f'Found {len(self.metafiles)} metadata files...')
1204
+ self.metafiles = (
1205
+ glob(self.exp_dir + os.sep.join([f"W*", "*", "movie", "*metadata.txt"]))
1206
+ + glob(self.exp_dir + os.sep.join([f"W*", "*", "*metadata.txt"]))
1207
+ + glob(self.exp_dir + os.sep.join([f"W*", "*metadata.txt"]))
1208
+ + glob(self.exp_dir + "*metadata.txt")
1209
+ )
1210
+ print(f"Found {len(self.metafiles)} metadata files...")
910
1211
  if len(self.metafiles) > 0:
911
1212
  self.metadata_found = True
912
1213
 
913
1214
  def switch_selection_mode(self, id):
914
- print(f'button {id} was clicked')
1215
+ print(f"button {id} was clicked")
915
1216
  for i in range(2):
916
1217
  if self.select_option[i].isChecked():
917
1218
  self.selection_mode = self.select_label[i]
918
- if self.selection_mode == 'name':
1219
+ if self.selection_mode == "name":
919
1220
  if len(self.metafiles) > 0:
920
1221
  self.position_scatter.hide()
921
1222
  self.line_choice_widget.show()
@@ -925,36 +1226,35 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
925
1226
  self.line_choice_widget.hide()
926
1227
 
927
1228
  def load_coordinates(self):
928
-
929
1229
  """
930
1230
  Read metadata and try to extract position coordinates
931
1231
  """
932
1232
 
933
1233
  self.no_meta = False
934
1234
  try:
935
- with open(self.metafiles[0], 'r') as f:
1235
+ with open(self.metafiles[0], "r") as f:
936
1236
  data = json.load(f)
937
- positions = data['Summary']['InitialPositionList']
1237
+ positions = data["Summary"]["InitialPositionList"]
938
1238
  except Exception as e:
939
- print(f'Trouble loading metadata: error {e}...')
1239
+ print(f"Trouble loading metadata: error {e}...")
940
1240
  return None
941
1241
 
942
1242
  for k in range(len(positions)):
943
- pos_label = positions[k]['Label']
1243
+ pos_label = positions[k]["Label"]
944
1244
  try:
945
- coords = positions[k]['DeviceCoordinatesUm']['XYStage']
1245
+ coords = positions[k]["DeviceCoordinatesUm"]["XYStage"]
946
1246
  except:
947
1247
  try:
948
- coords = positions[k]['DeviceCoordinatesUm']['PIXYStage']
1248
+ coords = positions[k]["DeviceCoordinatesUm"]["PIXYStage"]
949
1249
  except:
950
1250
  self.no_meta = True
951
1251
 
952
1252
  if not self.no_meta:
953
- files = self.df_pos_info['stack_path'].values
1253
+ files = self.df_pos_info["stack_path"].values
954
1254
  pos_loc = [pos_label in f for f in files]
955
- self.df_pos_info.loc[pos_loc, 'x'] = coords[0]
956
- self.df_pos_info.loc[pos_loc, 'y'] = coords[1]
957
- self.df_pos_info.loc[pos_loc, 'metadata_tag'] = pos_label
1255
+ self.df_pos_info.loc[pos_loc, "x"] = coords[0]
1256
+ self.df_pos_info.loc[pos_loc, "y"] = coords[1]
1257
+ self.df_pos_info.loc[pos_loc, "metadata_tag"] = pos_label
958
1258
 
959
1259
  def update_annot(self, ind):
960
1260
 
@@ -962,7 +1262,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
962
1262
  self.annot.xy = pos
963
1263
  text = self.scat_labels[ind["ind"][0]]
964
1264
  self.annot.set_text(text)
965
- self.annot.get_bbox_patch().set_facecolor('k')
1265
+ self.annot.get_bbox_patch().set_facecolor("k")
966
1266
  self.annot.get_bbox_patch().set_alpha(0.4)
967
1267
 
968
1268
  def hover(self, event):
@@ -979,22 +1279,28 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
979
1279
  self.fig_scatter.canvas.draw_idle()
980
1280
 
981
1281
  def unselect_position(self, event):
982
- print('unselecting position')
1282
+ print("unselecting position")
983
1283
  self.survival_window.canvas.clear()
984
1284
  ind = event.ind # index of selected position
985
- well_idx = self.df_pos_info.iloc[ind]['well_index'].values[0]
986
- selectedPos = self.df_pos_info.iloc[ind]['pos_path'].values[0]
987
- currentSelState = self.df_pos_info.iloc[ind]['select'].values[0]
1285
+ well_idx = self.df_pos_info.iloc[ind]["well_index"].values[0]
1286
+ selectedPos = self.df_pos_info.iloc[ind]["pos_path"].values[0]
1287
+ currentSelState = self.df_pos_info.iloc[ind]["select"].values[0]
988
1288
  if self.plot_options[0].isChecked() or self.plot_options[2].isChecked():
989
- self.df_pos_info.loc[self.df_pos_info['well_index'] == well_idx, 'select'] = not currentSelState
990
- self.df_well_info.loc[self.df_well_info['well_index'] == well_idx, 'select'] = not currentSelState
1289
+ self.df_pos_info.loc[
1290
+ self.df_pos_info["well_index"] == well_idx, "select"
1291
+ ] = not currentSelState
1292
+ self.df_well_info.loc[
1293
+ self.df_well_info["well_index"] == well_idx, "select"
1294
+ ] = not currentSelState
991
1295
  if len(self.well_indices) > 1:
992
1296
  self.well_display_options[well_idx].setChecked(not currentSelState)
993
1297
  else:
994
1298
  for p in self.pos_display_options:
995
1299
  p.setChecked(not currentSelState)
996
1300
  else:
997
- self.df_pos_info.loc[self.df_pos_info['pos_path'] == selectedPos, 'select'] = not currentSelState
1301
+ self.df_pos_info.loc[
1302
+ self.df_pos_info["pos_path"] == selectedPos, "select"
1303
+ ] = not currentSelState
998
1304
  if len(self.well_indices) <= 1:
999
1305
  self.pos_display_options[ind[0]].setChecked(not currentSelState)
1000
1306
 
@@ -1003,17 +1309,19 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
1003
1309
  self.plot_survivals(0)
1004
1310
 
1005
1311
  def select_survival_lines(self):
1006
- if self.plot_mode == 'wells':
1312
+ if self.plot_mode == "wells":
1007
1313
  selected_wells = []
1008
1314
  for i in range(len(self.well_display_options)):
1009
1315
  if self.well_display_options[i].isChecked():
1010
1316
  selected_wells.append(i)
1011
- self.df_well_info.loc[self.df_well_info['well_index'] == i, 'select'] = self.well_display_options[
1012
- i].isChecked()
1013
- self.df_pos_info.loc[self.df_pos_info['well_index'] == i, 'select'] = self.well_display_options[
1014
- i].isChecked()
1317
+ self.df_well_info.loc[
1318
+ self.df_well_info["well_index"] == i, "select"
1319
+ ] = self.well_display_options[i].isChecked()
1320
+ self.df_pos_info.loc[self.df_pos_info["well_index"] == i, "select"] = (
1321
+ self.well_display_options[i].isChecked()
1322
+ )
1015
1323
  if len(selected_wells) == 0:
1016
- print('No wells selected')
1324
+ print("No wells selected")
1017
1325
  self.ax.clear()
1018
1326
  else:
1019
1327
  self.ax.clear()
@@ -1025,8 +1333,9 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
1025
1333
  for i in range(len(self.pos_display_options)):
1026
1334
  if self.pos_display_options[i].isChecked():
1027
1335
  selected_pos.append(i + 1)
1028
- self.df_pos_info.loc[self.df_pos_info['pos_index'] == i, 'select'] = self.pos_display_options[
1029
- i].isChecked()
1336
+ self.df_pos_info.loc[self.df_pos_info["pos_index"] == i, "select"] = (
1337
+ self.pos_display_options[i].isChecked()
1338
+ )
1030
1339
  if len(selected_pos) == 0:
1031
1340
  self.ax.clear()
1032
1341
  else:
@@ -1046,13 +1355,23 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
1046
1355
  def plot_spatial_location(self):
1047
1356
 
1048
1357
  try:
1049
- self.sc = self.ax_scatter.scatter(self.df_pos_info["x"].values, self.df_pos_info["y"].values, picker=True,
1050
- pickradius=1, color=self.select_color(self.df_pos_info["select"].values))
1051
- self.scat_labels = self.df_pos_info['metadata_tag'].values
1358
+ self.sc = self.ax_scatter.scatter(
1359
+ self.df_pos_info["x"].values,
1360
+ self.df_pos_info["y"].values,
1361
+ picker=True,
1362
+ pickradius=1,
1363
+ color=self.select_color(self.df_pos_info["select"].values),
1364
+ )
1365
+ self.scat_labels = self.df_pos_info["metadata_tag"].values
1052
1366
  self.ax_scatter.invert_xaxis()
1053
- self.annot = self.ax_scatter.annotate("", xy=(0, 0), xytext=(10, 10), textcoords="offset points",
1054
- bbox=dict(boxstyle="round", fc="w"),
1055
- arrowprops=dict(arrowstyle="->"))
1367
+ self.annot = self.ax_scatter.annotate(
1368
+ "",
1369
+ xy=(0, 0),
1370
+ xytext=(10, 10),
1371
+ textcoords="offset points",
1372
+ bbox=dict(boxstyle="round", fc="w"),
1373
+ arrowprops=dict(arrowstyle="->"),
1374
+ )
1056
1375
  self.annot.set_visible(False)
1057
1376
  self.fig_scatter.canvas.mpl_connect("motion_notify_event", self.hover)
1058
1377
  self.fig_scatter.canvas.mpl_connect("pick_event", self.unselect_position)