celldetective 1.0.2.post1__py3-none-any.whl → 1.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. celldetective/__main__.py +7 -21
  2. celldetective/events.py +2 -44
  3. celldetective/extra_properties.py +62 -52
  4. celldetective/filters.py +4 -5
  5. celldetective/gui/__init__.py +1 -1
  6. celldetective/gui/analyze_block.py +37 -10
  7. celldetective/gui/btrack_options.py +24 -23
  8. celldetective/gui/classifier_widget.py +62 -19
  9. celldetective/gui/configure_new_exp.py +32 -35
  10. celldetective/gui/control_panel.py +120 -81
  11. celldetective/gui/gui_utils.py +674 -396
  12. celldetective/gui/json_readers.py +7 -6
  13. celldetective/gui/layouts.py +756 -0
  14. celldetective/gui/measurement_options.py +98 -513
  15. celldetective/gui/neighborhood_options.py +322 -270
  16. celldetective/gui/plot_measurements.py +1114 -0
  17. celldetective/gui/plot_signals_ui.py +21 -20
  18. celldetective/gui/process_block.py +449 -169
  19. celldetective/gui/retrain_segmentation_model_options.py +27 -26
  20. celldetective/gui/retrain_signal_model_options.py +25 -24
  21. celldetective/gui/seg_model_loader.py +31 -27
  22. celldetective/gui/signal_annotator.py +2326 -2295
  23. celldetective/gui/signal_annotator_options.py +18 -16
  24. celldetective/gui/styles.py +16 -1
  25. celldetective/gui/survival_ui.py +67 -39
  26. celldetective/gui/tableUI.py +337 -48
  27. celldetective/gui/thresholds_gui.py +75 -71
  28. celldetective/gui/viewers.py +743 -0
  29. celldetective/io.py +247 -27
  30. celldetective/measure.py +43 -263
  31. celldetective/models/segmentation_effectors/primNK_cfse/config_input.json +29 -0
  32. celldetective/models/segmentation_effectors/primNK_cfse/cp-cfse-transfer +0 -0
  33. celldetective/models/segmentation_effectors/primNK_cfse/training_instructions.json +37 -0
  34. celldetective/neighborhood.py +498 -27
  35. celldetective/preprocessing.py +1023 -0
  36. celldetective/scripts/analyze_signals.py +7 -0
  37. celldetective/scripts/measure_cells.py +12 -0
  38. celldetective/scripts/segment_cells.py +20 -4
  39. celldetective/scripts/track_cells.py +11 -0
  40. celldetective/scripts/train_segmentation_model.py +35 -34
  41. celldetective/segmentation.py +14 -9
  42. celldetective/signals.py +234 -329
  43. celldetective/tracking.py +2 -2
  44. celldetective/utils.py +602 -49
  45. celldetective-1.1.1.dist-info/METADATA +305 -0
  46. celldetective-1.1.1.dist-info/RECORD +84 -0
  47. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/top_level.txt +1 -0
  48. tests/__init__.py +0 -0
  49. tests/test_events.py +28 -0
  50. tests/test_filters.py +24 -0
  51. tests/test_io.py +70 -0
  52. tests/test_measure.py +141 -0
  53. tests/test_neighborhood.py +70 -0
  54. tests/test_preprocessing.py +37 -0
  55. tests/test_segmentation.py +93 -0
  56. tests/test_signals.py +135 -0
  57. tests/test_tracking.py +164 -0
  58. tests/test_utils.py +118 -0
  59. celldetective-1.0.2.post1.dist-info/METADATA +0 -221
  60. celldetective-1.0.2.post1.dist-info/RECORD +0 -66
  61. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/LICENSE +0 -0
  62. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/WHEEL +0 -0
  63. {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/entry_points.txt +0 -0
@@ -12,27 +12,28 @@ import numpy as np
12
12
  from superqt.fonticon import icon
13
13
  from fonticon_mdi6 import MDI6
14
14
  import os
15
+ from celldetective.gui import Styles
15
16
 
16
- class ConfigSignalAnnotator(QMainWindow):
17
+ class ConfigSignalAnnotator(QMainWindow, Styles):
17
18
 
18
19
  """
19
20
  UI to set normalization and animation parameters for the annotator tool.
20
21
 
21
22
  """
22
23
 
23
- def __init__(self, parent=None):
24
+ def __init__(self, parent_window=None):
24
25
 
25
26
  super().__init__()
26
- self.parent = parent
27
+ self.parent_window = parent_window
27
28
  self.setWindowTitle("Configure signal annotator")
28
- self.mode = self.parent.mode
29
- self.exp_dir = self.parent.exp_dir
29
+ self.mode = self.parent_window.mode
30
+ self.exp_dir = self.parent_window.exp_dir
30
31
  self.soft_path = get_software_location()
31
32
 
32
33
  if self.mode=="targets":
33
- self.instructions_path = self.parent.exp_dir + "configs/signal_annotator_config_targets.json"
34
+ self.instructions_path = self.parent_window.exp_dir + "configs/signal_annotator_config_targets.json"
34
35
  elif self.mode=="effectors":
35
- self.instructions_path = self.parent.exp_dir + "configs/signal_annotator_config_effectors.json"
36
+ self.instructions_path = self.parent_window.exp_dir + "configs/signal_annotator_config_effectors.json"
36
37
 
37
38
  exp_config = self.exp_dir +"config.ini"
38
39
  #self.config_path = self.exp_dir + self.config_name
@@ -41,7 +42,7 @@ class ConfigSignalAnnotator(QMainWindow):
41
42
  self.channels = np.array(self.channels)
42
43
  self.log_option = False
43
44
 
44
- self.screen_height = self.parent.parent.parent.screen_height
45
+ self.screen_height = self.parent_window.parent_window.parent_window.screen_height
45
46
  center_window(self)
46
47
 
47
48
  self.setMinimumHeight(int(0.4*self.screen_height))
@@ -49,6 +50,7 @@ class ConfigSignalAnnotator(QMainWindow):
49
50
  self.populate_widget()
50
51
  #self.load_previous_measurement_instructions()
51
52
 
53
+
52
54
  def populate_widget(self):
53
55
 
54
56
  """
@@ -59,13 +61,13 @@ class ConfigSignalAnnotator(QMainWindow):
59
61
  self.scroll_area = QScrollArea(self)
60
62
  self.button_widget = QWidget()
61
63
 
62
- main_layout = QVBoxLayout()
63
- main_layout.setContentsMargins(30,30,30,30)
64
+ self.main_layout = QVBoxLayout()
65
+ self.main_layout.setContentsMargins(30,30,30,30)
64
66
 
65
67
  sub_layout = QVBoxLayout()
66
68
  sub_layout.setContentsMargins(10,10,10,20)
67
69
 
68
- self.button_widget.setLayout(main_layout)
70
+ self.button_widget.setLayout(self.main_layout)
69
71
  sub_layout.setContentsMargins(30,30,30,30)
70
72
 
71
73
  sub_layout.addWidget(QLabel('Modality: '))
@@ -85,13 +87,13 @@ class ConfigSignalAnnotator(QMainWindow):
85
87
  self.percentile_btn = QPushButton()
86
88
  self.percentile_btn.setIcon(icon(MDI6.percent_circle_outline,color="black"))
87
89
  self.percentile_btn.setIconSize(QSize(20, 20))
88
- self.percentile_btn.setStyleSheet(self.parent.parent.parent.button_select_all)
90
+ self.percentile_btn.setStyleSheet(self.button_select_all)
89
91
  self.percentile_btn.setToolTip("Switch to percentile normalization values.")
90
92
  self.percentile_btn.clicked.connect(self.switch_to_absolute_normalization_mode)
91
93
 
92
94
  self.log_btn = QPushButton()
93
95
  self.log_btn.setIcon(icon(MDI6.math_log,color="black"))
94
- self.log_btn.setStyleSheet(self.parent.parent.parent.button_select_all)
96
+ self.log_btn.setStyleSheet(self.button_select_all)
95
97
  self.log_btn.clicked.connect(self.switch_to_log)
96
98
  self.log_btn.setToolTip("Log-transform the intensities.")
97
99
  self.log_btn.setIconSize(QSize(20, 20))
@@ -168,12 +170,12 @@ class ConfigSignalAnnotator(QMainWindow):
168
170
  hbox_interval.addWidget(self.interval_slider, 80)
169
171
  sub_layout.addLayout(hbox_interval)
170
172
 
171
- main_layout.addLayout(sub_layout)
173
+ self.main_layout.addLayout(sub_layout)
172
174
 
173
175
  self.submit_btn = QPushButton('Save')
174
- self.submit_btn.setStyleSheet(self.parent.parent.parent.button_style_sheet)
176
+ self.submit_btn.setStyleSheet(self.button_style_sheet)
175
177
  self.submit_btn.clicked.connect(self.write_instructions)
176
- main_layout.addWidget(self.submit_btn)
178
+ self.main_layout.addWidget(self.submit_btn)
177
179
 
178
180
 
179
181
  self.button_widget.adjustSize()
@@ -4,6 +4,14 @@ class Styles(object):
4
4
 
5
5
  self.init_button_styles()
6
6
  self.init_tab_styles()
7
+ self.init_label_styles()
8
+
9
+ self.celldetective_blue = "#1565c0"
10
+
11
+ self.action_lbl_style_sheet = """
12
+ font-size: 10px;
13
+ padding-left: 10px;
14
+ """
7
15
 
8
16
  def init_button_styles(self):
9
17
 
@@ -214,4 +222,11 @@ class Styles(object):
214
222
  QTabBar::tab:left:only-one, QTabBar::tab:right:only-one {
215
223
  margin-bottom: 0;
216
224
  }
217
- """
225
+ """
226
+
227
+ def init_label_styles(self):
228
+
229
+ self.block_title = '''
230
+ font-weight: bold;
231
+ padding: 0px;
232
+ '''
@@ -2,7 +2,7 @@ from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QScrollArea,
2
2
  from PyQt5.QtCore import Qt, QSize
3
3
  from PyQt5.QtGui import QIcon, QDoubleValidator
4
4
  from celldetective.gui.gui_utils import center_window, FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, GeometryChoice, OperationChoice
5
- from superqt import QLabeledDoubleRangeSlider, QLabeledDoubleSlider,QLabeledSlider
5
+ from superqt import QLabeledDoubleRangeSlider, QLabeledDoubleSlider,QLabeledSlider, QColormapComboBox
6
6
  from superqt.fonticon import icon
7
7
  from fonticon_mdi6 import MDI6
8
8
  from celldetective.utils import extract_experiment_channels, get_software_location, _extract_labels_from_config
@@ -26,40 +26,39 @@ from tqdm import tqdm
26
26
  from lifelines import KaplanMeierFitter
27
27
  import matplotlib.cm as mcm
28
28
  import math
29
- from celldetective.events import switch_to_events_v2
29
+ from celldetective.events import switch_to_events
30
+ from celldetective.gui import Styles
31
+ from matplotlib import colormaps
30
32
 
31
- class ConfigSurvival(QWidget):
33
+ class ConfigSurvival(QWidget, Styles):
32
34
 
33
35
  """
34
36
  UI to set survival instructions.
35
37
 
36
38
  """
37
39
 
38
- def __init__(self, parent=None):
40
+ def __init__(self, parent_window=None):
39
41
 
40
42
  super().__init__()
41
- self.parent = parent
43
+ self.parent_window = parent_window
42
44
  self.setWindowTitle("Configure survival")
43
- self.setWindowIcon(QIcon(os.sep.join(['celldetective','icons','mexican-hat.png'])))
45
+ self.setWindowIcon(QIcon(os.sep.join(['celldetective','icons','logo.png'])))
44
46
 
45
- self.exp_dir = self.parent.exp_dir
47
+ self.exp_dir = self.parent_window.exp_dir
46
48
  self.soft_path = get_software_location()
47
49
  self.exp_config = self.exp_dir +"config.ini"
48
- self.wells = np.array(self.parent.parent.wells,dtype=str)
50
+ self.wells = np.array(self.parent_window.parent_window.wells,dtype=str)
49
51
  self.well_labels = _extract_labels_from_config(self.exp_config,len(self.wells))
50
- self.FrameToMin = self.parent.parent.FrameToMin
52
+ self.FrameToMin = self.parent_window.parent_window.FrameToMin
51
53
  self.float_validator = QDoubleValidator()
52
54
  self.auto_close = False
53
55
 
54
- print('Parent wells: ', self.wells)
55
-
56
-
57
- self.well_option = self.parent.parent.well_list.currentIndex()
58
- self.position_option = self.parent.parent.position_list.currentIndex()
56
+ self.well_option = self.parent_window.parent_window.well_list.currentIndex()
57
+ self.position_option = self.parent_window.parent_window.position_list.currentIndex()
59
58
  self.interpret_pos_location()
60
59
  #self.config_path = self.exp_dir + self.config_name
61
60
 
62
- self.screen_height = self.parent.parent.parent.screen_height
61
+ self.screen_height = self.parent_window.parent_window.parent_window.screen_height
63
62
  center_window(self)
64
63
 
65
64
  self.setMinimumWidth(350)
@@ -69,6 +68,7 @@ class ConfigSurvival(QWidget):
69
68
  #self.load_previous_measurement_instructions()
70
69
  if self.auto_close:
71
70
  self.close()
71
+ self.setAttribute(Qt.WA_DeleteOnClose)
72
72
 
73
73
  def interpret_pos_location(self):
74
74
 
@@ -109,9 +109,10 @@ class ConfigSurvival(QWidget):
109
109
  main_layout.addWidget(panel_title, alignment=Qt.AlignCenter)
110
110
 
111
111
 
112
- labels = [QLabel('population: '), QLabel('time of\ninterest: '), QLabel('time of\nreference: '), QLabel('cmap: ')] #QLabel('class: '),
113
- self.cb_options = [['targets','effectors'],['t0','first detection'], ['0','first detection', 't0'], list(plt.colormaps())] #['class'],
112
+ labels = [QLabel('population: '), QLabel('time of\nreference: '), QLabel('time of\ninterest: '), QLabel('exclude\nclass: '), QLabel('cmap: ')] #QLabel('class: '),
113
+ self.cb_options = [['targets','effectors'], ['0','t_firstdetection'], ['t0'], ['--'], list(plt.colormaps())] #['class'],
114
114
  self.cbs = [QComboBox() for i in range(len(labels))]
115
+ self.cbs[-1] = QColormapComboBox()
115
116
  self.cbs[0].currentIndexChanged.connect(self.set_classes_and_times)
116
117
 
117
118
  choice_layout = QVBoxLayout()
@@ -120,12 +121,20 @@ class ConfigSurvival(QWidget):
120
121
  hbox = QHBoxLayout()
121
122
  hbox.addWidget(labels[i], 33)
122
123
  hbox.addWidget(self.cbs[i],66)
123
- self.cbs[i].addItems(self.cb_options[i])
124
+ if i < len(labels)-1:
125
+ self.cbs[i].addItems(self.cb_options[i])
124
126
  choice_layout.addLayout(hbox)
127
+
128
+ for cm in list(colormaps):
129
+ try:
130
+ self.cbs[-1].addColormap(cm)
131
+ except:
132
+ pass
133
+
125
134
  main_layout.addLayout(choice_layout)
126
135
 
127
- self.cbs[0].setCurrentIndex(1)
128
136
  self.cbs[0].setCurrentIndex(0)
137
+ self.cbs[1].setCurrentText('t_firstdetection')
129
138
 
130
139
  time_calib_layout = QHBoxLayout()
131
140
  time_calib_layout.setContentsMargins(20,20,20,20)
@@ -137,7 +146,7 @@ class ConfigSurvival(QWidget):
137
146
  main_layout.addLayout(time_calib_layout)
138
147
 
139
148
  self.submit_btn = QPushButton('Submit')
140
- self.submit_btn.setStyleSheet(self.parent.parent.parent.button_style_sheet)
149
+ self.submit_btn.setStyleSheet(self.button_style_sheet)
141
150
  self.submit_btn.clicked.connect(self.process_survival)
142
151
  main_layout.addWidget(self.submit_btn)
143
152
 
@@ -150,7 +159,7 @@ class ConfigSurvival(QWidget):
150
159
  def set_classes_and_times(self):
151
160
 
152
161
  # Look for all classes and times
153
- tables = glob(self.exp_dir+os.sep.join(['W*','*','output','tables',f'trajectories_*']))
162
+ tables = glob(self.exp_dir+os.sep.join(['W*','*','output','tables',f'trajectories_*.csv']))
154
163
  self.all_columns = []
155
164
  for tab in tables:
156
165
  cols = pd.read_csv(tab, nrows=1,encoding_errors='ignore').columns.tolist()
@@ -158,6 +167,8 @@ class ConfigSurvival(QWidget):
158
167
  self.all_columns = np.unique(self.all_columns)
159
168
  #class_idx = np.array([s.startswith('class_') for s in self.all_columns])
160
169
  time_idx = np.array([s.startswith('t_') for s in self.all_columns])
170
+ class_idx = np.array([s.startswith('class') for s in self.all_columns])
171
+
161
172
  # class_columns = list(self.all_columns[class_idx])
162
173
  # for c in ['class_id', 'class_color']:
163
174
  # if c in class_columns:
@@ -170,12 +181,22 @@ class ConfigSurvival(QWidget):
170
181
  self.auto_close = True
171
182
  return None
172
183
 
173
- self.cbs[1].clear()
174
- self.cbs[1].addItems(np.unique(self.cb_options[1]+time_columns))
184
+ try:
185
+ class_columns = list(self.all_columns[class_idx])
186
+ self.cbs[3].clear()
187
+ self.cbs[3].addItems(np.unique(self.cb_options[3]+class_columns))
188
+ except:
189
+ print('no column starts with class')
190
+ self.auto_close = True
191
+ return None
175
192
 
176
193
  self.cbs[2].clear()
177
194
  self.cbs[2].addItems(np.unique(self.cb_options[2]+time_columns))
178
195
 
196
+ self.cbs[1].clear()
197
+ self.cbs[1].addItems(np.unique(self.cb_options[1]+time_columns))
198
+ self.cbs[1].setCurrentText('t_firstdetection')
199
+
179
200
  # self.cbs[3].clear()
180
201
  # self.cbs[3].addItems(np.unique(self.cb_options[3]+class_columns))
181
202
 
@@ -186,7 +207,7 @@ class ConfigSurvival(QWidget):
186
207
  self.FrameToMin = float(self.time_calibration_le.text().replace(',','.'))
187
208
  print(self.FrameToMin, 'set')
188
209
 
189
- self.time_of_interest = self.cbs[1].currentText()
210
+ self.time_of_interest = self.cbs[2].currentText()
190
211
  if self.time_of_interest=="t0":
191
212
  self.class_of_interest = "class"
192
213
  else:
@@ -194,7 +215,14 @@ class ConfigSurvival(QWidget):
194
215
 
195
216
  # read instructions from combobox options
196
217
  self.load_available_tables_local()
218
+
197
219
  if self.df is not None:
220
+
221
+ excluded_class = self.cbs[3].currentText()
222
+ if excluded_class!='--':
223
+ print(f"Excluding {excluded_class}...")
224
+ self.df = self.df.loc[~(self.df[excluded_class].isin([0,2])),:]
225
+
198
226
  self.compute_survival_functions()
199
227
  # prepare survival
200
228
 
@@ -216,7 +244,7 @@ class ConfigSurvival(QWidget):
216
244
 
217
245
  self.legend_btn = QPushButton('')
218
246
  self.legend_btn.setIcon(icon(MDI6.text_box,color="black"))
219
- self.legend_btn.setStyleSheet(self.parent.parent.parent.button_select_all)
247
+ self.legend_btn.setStyleSheet(self.button_select_all)
220
248
  self.legend_btn.setToolTip('Show or hide the legend')
221
249
  self.legend_visible = True
222
250
  self.legend_btn.clicked.connect(self.show_hide_legend)
@@ -225,7 +253,7 @@ class ConfigSurvival(QWidget):
225
253
 
226
254
  self.log_btn = QPushButton('')
227
255
  self.log_btn.setIcon(icon(MDI6.math_log,color="black"))
228
- self.log_btn.setStyleSheet(self.parent.parent.parent.button_select_all)
256
+ self.log_btn.setStyleSheet(self.button_select_all)
229
257
  self.log_btn.clicked.connect(self.switch_to_log)
230
258
  self.log_btn.setToolTip('Enable or disable log scale')
231
259
  plot_buttons_hbox.addWidget(self.log_btn, 5, alignment=Qt.AlignRight)
@@ -369,12 +397,12 @@ class ConfigSurvival(QWidget):
369
397
 
370
398
  """
371
399
 
372
- self.well_option = self.parent.parent.well_list.currentIndex()
400
+ self.well_option = self.parent_window.parent_window.well_list.currentIndex()
373
401
  if self.well_option==len(self.wells):
374
402
  wo = '*'
375
403
  else:
376
404
  wo = self.well_option
377
- self.position_option = self.parent.parent.position_list.currentIndex()
405
+ self.position_option = self.parent_window.parent_window.position_list.currentIndex()
378
406
  if self.position_option==0:
379
407
  po = '*'
380
408
  else:
@@ -403,14 +431,14 @@ class ConfigSurvival(QWidget):
403
431
  for block,movie_group in self.df.groupby(['well','position']):
404
432
  try:
405
433
  classes = movie_group.groupby('TRACK_ID')[self.class_of_interest].min().values
406
- times = movie_group.groupby('TRACK_ID')[self.cbs[1].currentText()].min().values
434
+ times = movie_group.groupby('TRACK_ID')[self.cbs[2].currentText()].min().values
407
435
  except Exception as e:
408
436
  print(e)
409
437
  continue
410
438
  max_times = movie_group.groupby('TRACK_ID')['FRAME'].max().values
411
439
  first_detections = None
412
440
 
413
- if self.cbs[2].currentText()=='first detection':
441
+ if self.cbs[1].currentText()=='first detection':
414
442
  left_censored = True
415
443
 
416
444
  first_detections = []
@@ -427,17 +455,17 @@ class ConfigSurvival(QWidget):
427
455
  else:
428
456
  continue
429
457
 
430
- elif self.cbs[2].currentText().startswith('t'):
458
+ elif self.cbs[1].currentText().startswith('t'):
431
459
  left_censored = True
432
- first_detections = movie_group.groupby('TRACK_ID')[self.cbs[2].currentText()].max().values
460
+ first_detections = movie_group.groupby('TRACK_ID')[self.cbs[1].currentText()].max().values
433
461
  print(first_detections)
434
462
 
435
463
 
436
- if self.cbs[2].currentText()=='first detection' or self.cbs[2].currentText().startswith('t'):
464
+ if self.cbs[1].currentText()=='first detection' or self.cbs[1].currentText().startswith('t'):
437
465
  left_censored = True
438
466
  else:
439
467
  left_censored = False
440
- events, survival_times = switch_to_events_v2(classes, times, max_times, first_detections, left_censored=left_censored, FrameToMin=self.FrameToMin)
468
+ events, survival_times = switch_to_events(classes, times, max_times, first_detections, left_censored=left_censored, FrameToMin=self.FrameToMin)
441
469
  ks = KaplanMeierFitter()
442
470
  if len(events)>0:
443
471
  ks.fit(survival_times, event_observed=events)
@@ -455,14 +483,14 @@ class ConfigSurvival(QWidget):
455
483
  for block,movie_group in well_group.groupby('position'):
456
484
  try:
457
485
  classes = movie_group.groupby('TRACK_ID')[self.class_of_interest].min().values
458
- times = movie_group.groupby('TRACK_ID')[self.cbs[1].currentText()].min().values
486
+ times = movie_group.groupby('TRACK_ID')[self.cbs[2].currentText()].min().values
459
487
  except Exception as e:
460
488
  print(e)
461
489
  continue
462
490
  max_times = movie_group.groupby('TRACK_ID')['FRAME'].max().values
463
491
  first_detections = None
464
492
 
465
- if self.cbs[2].currentText()=='first detection':
493
+ if self.cbs[1].currentText()=='first detection':
466
494
 
467
495
  left_censored = True
468
496
  first_detections = []
@@ -477,9 +505,9 @@ class ConfigSurvival(QWidget):
477
505
  # think about assymmetry with class and times
478
506
  continue
479
507
 
480
- elif self.cbs[2].currentText().startswith('t'):
508
+ elif self.cbs[1].currentText().startswith('t'):
481
509
  left_censored = True
482
- first_detections = movie_group.groupby('TRACK_ID')[self.cbs[2].currentText()].max().values
510
+ first_detections = movie_group.groupby('TRACK_ID')[self.cbs[1].currentText()].max().values
483
511
 
484
512
  else:
485
513
  pass
@@ -494,7 +522,7 @@ class ConfigSurvival(QWidget):
494
522
  well_first_detections = None
495
523
 
496
524
  print(f"{well_classes=}; {well_times=}")
497
- events, survival_times = switch_to_events_v2(well_classes, well_times, well_max_times, well_first_detections,left_censored=left_censored, FrameToMin=self.FrameToMin)
525
+ events, survival_times = switch_to_events(well_classes, well_times, well_max_times, well_first_detections,left_censored=left_censored, FrameToMin=self.FrameToMin)
498
526
  print(f"{events=}; {survival_times=}")
499
527
  ks = KaplanMeierFitter()
500
528
  if len(survival_times)>0: