celldetective 1.0.2__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 (66) hide show
  1. celldetective/__init__.py +2 -0
  2. celldetective/__main__.py +432 -0
  3. celldetective/datasets/segmentation_annotations/blank +0 -0
  4. celldetective/datasets/signal_annotations/blank +0 -0
  5. celldetective/events.py +149 -0
  6. celldetective/extra_properties.py +100 -0
  7. celldetective/filters.py +89 -0
  8. celldetective/gui/__init__.py +20 -0
  9. celldetective/gui/about.py +44 -0
  10. celldetective/gui/analyze_block.py +563 -0
  11. celldetective/gui/btrack_options.py +898 -0
  12. celldetective/gui/classifier_widget.py +386 -0
  13. celldetective/gui/configure_new_exp.py +532 -0
  14. celldetective/gui/control_panel.py +438 -0
  15. celldetective/gui/gui_utils.py +495 -0
  16. celldetective/gui/json_readers.py +113 -0
  17. celldetective/gui/measurement_options.py +1425 -0
  18. celldetective/gui/neighborhood_options.py +452 -0
  19. celldetective/gui/plot_signals_ui.py +1042 -0
  20. celldetective/gui/process_block.py +1055 -0
  21. celldetective/gui/retrain_segmentation_model_options.py +706 -0
  22. celldetective/gui/retrain_signal_model_options.py +643 -0
  23. celldetective/gui/seg_model_loader.py +460 -0
  24. celldetective/gui/signal_annotator.py +2388 -0
  25. celldetective/gui/signal_annotator_options.py +340 -0
  26. celldetective/gui/styles.py +217 -0
  27. celldetective/gui/survival_ui.py +903 -0
  28. celldetective/gui/tableUI.py +608 -0
  29. celldetective/gui/thresholds_gui.py +1300 -0
  30. celldetective/icons/logo-large.png +0 -0
  31. celldetective/icons/logo.png +0 -0
  32. celldetective/icons/signals_icon.png +0 -0
  33. celldetective/icons/splash-test.png +0 -0
  34. celldetective/icons/splash.png +0 -0
  35. celldetective/icons/splash0.png +0 -0
  36. celldetective/icons/survival2.png +0 -0
  37. celldetective/icons/vignette_signals2.png +0 -0
  38. celldetective/icons/vignette_signals2.svg +114 -0
  39. celldetective/io.py +2050 -0
  40. celldetective/links/zenodo.json +561 -0
  41. celldetective/measure.py +1258 -0
  42. celldetective/models/segmentation_effectors/blank +0 -0
  43. celldetective/models/segmentation_generic/blank +0 -0
  44. celldetective/models/segmentation_targets/blank +0 -0
  45. celldetective/models/signal_detection/blank +0 -0
  46. celldetective/models/tracking_configs/mcf7.json +68 -0
  47. celldetective/models/tracking_configs/ricm.json +203 -0
  48. celldetective/models/tracking_configs/ricm2.json +203 -0
  49. celldetective/neighborhood.py +717 -0
  50. celldetective/scripts/analyze_signals.py +51 -0
  51. celldetective/scripts/measure_cells.py +275 -0
  52. celldetective/scripts/segment_cells.py +212 -0
  53. celldetective/scripts/segment_cells_thresholds.py +140 -0
  54. celldetective/scripts/track_cells.py +206 -0
  55. celldetective/scripts/train_segmentation_model.py +246 -0
  56. celldetective/scripts/train_signal_model.py +49 -0
  57. celldetective/segmentation.py +712 -0
  58. celldetective/signals.py +2826 -0
  59. celldetective/tracking.py +974 -0
  60. celldetective/utils.py +1681 -0
  61. celldetective-1.0.2.dist-info/LICENSE +674 -0
  62. celldetective-1.0.2.dist-info/METADATA +192 -0
  63. celldetective-1.0.2.dist-info/RECORD +66 -0
  64. celldetective-1.0.2.dist-info/WHEEL +5 -0
  65. celldetective-1.0.2.dist-info/entry_points.txt +2 -0
  66. celldetective-1.0.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,563 @@
1
+ from PyQt5.QtWidgets import QFrame, QGridLayout, QComboBox, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QCheckBox, QMessageBox
2
+ from PyQt5.QtCore import Qt, QSize
3
+ from PyQt5.QtGui import QIcon
4
+
5
+ from superqt.fonticon import icon
6
+ from fonticon_mdi6 import MDI6
7
+ import gc
8
+ from celldetective.io import get_segmentation_models_list, control_segmentation_napari, get_signal_models_list, control_tracking_btrack
9
+ from celldetective.gui import ConfigSurvival, ConfigSignalPlot
10
+ from celldetective.gui.gui_utils import QHSeperationLine
11
+ from celldetective.segmentation import segment_at_position, segment_from_threshold_at_position
12
+ from celldetective.tracking import track_at_position
13
+ from celldetective.measure import measure_at_position
14
+ from celldetective.signals import analyze_signals_at_position
15
+ import numpy as np
16
+ from glob import glob
17
+ from natsort import natsorted
18
+ import os
19
+ import pandas as pd
20
+
21
+ class AnalysisPanel(QFrame):
22
+ def __init__(self, parent, title=None):
23
+
24
+ super().__init__()
25
+ self.parent = parent
26
+ self.title = title
27
+ if self.title is None:
28
+ self.title=''
29
+ self.exp_channels = self.parent.exp_channels
30
+ self.exp_dir = self.parent.exp_dir
31
+ self.soft_path = self.parent.parent.soft_path
32
+
33
+ self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
34
+ self.grid = QVBoxLayout(self)
35
+ self.generate_header()
36
+
37
+ def generate_header(self):
38
+
39
+ """
40
+ Read the mode and prepare a collapsable block to process a specific cell population.
41
+
42
+ """
43
+
44
+ panel_title = QLabel(self.title)
45
+ panel_title.setStyleSheet("""
46
+ font-weight: bold;
47
+ padding: 0px;
48
+ """)
49
+
50
+ self.grid.addWidget(panel_title, alignment=Qt.AlignCenter)
51
+
52
+ self.survival_btn = QPushButton("plot survival")
53
+ self.survival_btn.setIcon(QIcon(QIcon(os.sep.join([self.soft_path,'celldetective','icons','survival2.png']))))
54
+ self.survival_btn.setStyleSheet(self.parent.parent.button_style_sheet_2)
55
+ self.survival_btn.setIconSize(QSize(35, 35))
56
+ self.survival_btn.clicked.connect(self.configure_survival)
57
+ self.grid.addWidget(self.survival_btn)
58
+
59
+
60
+ self.plot_signal_btn = QPushButton("plot signals")
61
+ self.plot_signal_btn.setIcon(QIcon(QIcon(os.sep.join([self.soft_path,'celldetective','icons','signals_icon.png']))))
62
+ self.plot_signal_btn.setStyleSheet(self.parent.parent.button_style_sheet_2)
63
+ self.plot_signal_btn.setIconSize(QSize(35, 35))
64
+ self.plot_signal_btn.clicked.connect(self.configure_plot_signals)
65
+ self.grid.addWidget(self.plot_signal_btn)
66
+
67
+
68
+ def configure_survival(self):
69
+ print('survival analysis starting!!!')
70
+ self.configSurvival = ConfigSurvival(self)
71
+ self.configSurvival.show()
72
+
73
+ def configure_plot_signals(self):
74
+ print('plot signal analysis starting!!!')
75
+ self.ConfigSignalPlot = ConfigSignalPlot(self)
76
+ self.ConfigSignalPlot.show()
77
+
78
+
79
+ # self.select_all_btn = QPushButton()
80
+ # self.select_all_btn.setIcon(icon(MDI6.checkbox_blank_outline,color="black"))
81
+ # self.select_all_btn.setIconSize(QSize(20, 20))
82
+ # self.all_ticked = False
83
+ # self.select_all_btn.clicked.connect(self.tick_all_actions)
84
+ # self.select_all_btn.setStyleSheet(self.parent.parent.button_select_all)
85
+ # self.grid.addWidget(self.select_all_btn, 0, 0, 1, 4, alignment=Qt.AlignLeft)
86
+ # #self.to_disable.append(self.all_tc_actions)
87
+
88
+ # self.collapse_btn = QPushButton()
89
+ # self.collapse_btn.setIcon(icon(MDI6.chevron_down,color="black"))
90
+ # self.collapse_btn.setIconSize(QSize(25, 25))
91
+ # self.collapse_btn.setStyleSheet(self.parent.parent.button_select_all)
92
+ # self.grid.addWidget(self.collapse_btn, 0, 0, 1, 4, alignment=Qt.AlignRight)
93
+
94
+ # self.populate_contents()
95
+ # self.grid.addWidget(self.ContentsFrame, 1, 0, 1, 4, alignment=Qt.AlignTop)
96
+ # self.collapse_btn.clicked.connect(lambda: self.ContentsFrame.setHidden(not self.ContentsFrame.isHidden()))
97
+ # self.collapse_btn.clicked.connect(self.collapse_advanced)
98
+ # self.ContentsFrame.hide()
99
+
100
+ # def collapse_advanced(self):
101
+ # if self.ContentsFrame.isHidden():
102
+ # self.collapse_btn.setIcon(icon(MDI6.chevron_down,color="black"))
103
+ # self.collapse_btn.setIconSize(QSize(20, 20))
104
+ # self.parent.w.adjustSize()
105
+ # self.parent.adjustSize()
106
+ # else:
107
+ # self.collapse_btn.setIcon(icon(MDI6.chevron_up,color="black"))
108
+ # self.collapse_btn.setIconSize(QSize(20, 20))
109
+ # self.parent.w.adjustSize()
110
+ # self.parent.adjustSize()
111
+
112
+ # def populate_contents(self):
113
+
114
+ # self.ContentsFrame = QFrame()
115
+ # self.grid_contents = QGridLayout(self.ContentsFrame)
116
+ # self.grid_contents.setContentsMargins(0,0,0,0)
117
+ # self.generate_segmentation_options()
118
+ # self.generate_tracking_options()
119
+ # self.generate_measure_options()
120
+ # self.generate_signal_analysis_options()
121
+
122
+ # self.grid_contents.addWidget(QHSeperationLine(), 9, 0, 1, 4)
123
+ # self.view_tab_btn = QPushButton("View table")
124
+ # self.view_tab_btn.setStyleSheet(self.parent.parent.button_style_sheet_2)
125
+ # self.view_tab_btn.clicked.connect(self.view_table_ui)
126
+ # self.view_tab_btn.setToolTip('poop twice a day for a healthy gut')
127
+ # self.view_tab_btn.setIcon(icon(MDI6.table,color="#1565c0"))
128
+ # self.view_tab_btn.setIconSize(QSize(20, 20))
129
+ # self.view_tab_btn.setEnabled(False)
130
+ # self.grid_contents.addWidget(self.view_tab_btn, 10, 0, 1, 4)
131
+
132
+ # self.grid_contents.addWidget(QHSeperationLine(), 9, 0, 1, 4)
133
+ # self.submit_btn = QPushButton("Submit")
134
+ # self.submit_btn.setStyleSheet(self.parent.parent.button_style_sheet_2)
135
+ # self.submit_btn.clicked.connect(self.process_population)
136
+ # self.grid_contents.addWidget(self.submit_btn, 11, 0, 1, 4)
137
+
138
+ # def generate_measure_options(self):
139
+
140
+ # measure_layout = QHBoxLayout()
141
+
142
+ # self.measure_action = QCheckBox("MEASURE")
143
+ # self.measure_action.setStyleSheet("""
144
+ # font-size: 10px;
145
+ # padding-left: 10px;
146
+ # padding-top: 5px;
147
+ # """)
148
+ # self.measure_action.setIcon(icon(MDI6.eyedropper,color="black"))
149
+ # self.measure_action.setIconSize(QSize(20, 20))
150
+ # self.measure_action.setToolTip("Measure the intensity of the cells, \ndetect death events using the selected pre-trained model, \nformat the data for visualization, \nremove cells that are already dead and \nsave the result in a table.")
151
+ # measure_layout.addWidget(self.measure_action, 90)
152
+ # #self.to_disable.append(self.measure_action_tc)
153
+
154
+ # self.measurements_config_btn = QPushButton()
155
+ # self.measurements_config_btn.setIcon(icon(MDI6.cog_outline,color="black"))
156
+ # self.measurements_config_btn.setIconSize(QSize(20, 20))
157
+ # self.measurements_config_btn.setToolTip("Configure measurements.")
158
+ # self.measurements_config_btn.setStyleSheet(self.parent.parent.button_select_all)
159
+ # self.measurements_config_btn.clicked.connect(self.open_measurement_configuration_ui)
160
+ # measure_layout.addWidget(self.measurements_config_btn, 6) #4,2,1,1, alignment=Qt.AlignRight
161
+
162
+ # self.grid_contents.addLayout(measure_layout,5,0,1,4)
163
+
164
+ # def generate_signal_analysis_options(self):
165
+
166
+ # signal_layout = QVBoxLayout()
167
+ # signal_hlayout = QHBoxLayout()
168
+ # self.signal_analysis_action = QCheckBox("SIGNAL ANALYSIS")
169
+ # self.signal_analysis_action.setStyleSheet("""
170
+ # font-size: 10px;
171
+ # padding-left: 10px;
172
+ # padding-top: 5px;
173
+ # """)
174
+ # self.signal_analysis_action.setIcon(icon(MDI6.chart_bell_curve_cumulative,color="black"))
175
+ # self.signal_analysis_action.setIconSize(QSize(20, 20))
176
+ # self.signal_analysis_action.setToolTip("Analyze cell signals using deep learning or a fit procedure.")
177
+ # self.signal_analysis_action.toggled.connect(self.enable_signal_model_list)
178
+ # signal_hlayout.addWidget(self.signal_analysis_action, 90)
179
+
180
+ # self.check_signals_btn = QPushButton()
181
+ # self.check_signals_btn.setIcon(icon(MDI6.eye_check_outline,color="black"))
182
+ # self.check_signals_btn.setIconSize(QSize(20, 20))
183
+ # self.check_signals_btn.clicked.connect(self.check_signals)
184
+ # self.check_signals_btn.setStyleSheet(self.parent.parent.button_select_all)
185
+ # signal_hlayout.addWidget(self.check_signals_btn, 6)
186
+
187
+ # self.config_signal_annotator_btn = QPushButton()
188
+ # self.config_signal_annotator_btn.setIcon(icon(MDI6.cog_outline,color="black"))
189
+ # self.config_signal_annotator_btn.setIconSize(QSize(20, 20))
190
+ # self.config_signal_annotator_btn.setToolTip("Configure the animation of the annotation tool.")
191
+ # self.config_signal_annotator_btn.setStyleSheet(self.parent.parent.button_select_all)
192
+ # self.config_signal_annotator_btn.clicked.connect(self.open_signal_annotator_configuration_ui)
193
+ # signal_hlayout.addWidget(self.config_signal_annotator_btn, 6)
194
+
195
+ # #self.to_disable.append(self.measure_action_tc)
196
+ # signal_layout.addLayout(signal_hlayout)
197
+
198
+ # model_zoo_layout = QHBoxLayout()
199
+ # model_zoo_layout.addWidget(QLabel("Model zoo:"),90)
200
+
201
+ # self.signal_models_list = QComboBox()
202
+ # self.signal_models_list.setEnabled(False)
203
+ # self.refresh_signal_models()
204
+ # #self.to_disable.append(self.cell_models_list)
205
+
206
+ # self.train_signal_model_btn = QPushButton("TRAIN")
207
+ # self.train_signal_model_btn.setToolTip("Open a dialog box to create a new target segmentation model.")
208
+ # self.train_signal_model_btn.setIcon(icon(MDI6.redo_variant,color='black'))
209
+ # self.train_signal_model_btn.setIconSize(QSize(20, 20))
210
+ # self.train_signal_model_btn.setStyleSheet(self.parent.parent.button_style_sheet_3)
211
+ # model_zoo_layout.addWidget(self.train_signal_model_btn, 5)
212
+ # self.train_signal_model_btn.clicked.connect(self.open_signal_model_config_ui)
213
+ # signal_layout.addLayout(model_zoo_layout)
214
+ # signal_layout.addWidget(self.signal_models_list)
215
+
216
+ # self.grid_contents.addLayout(signal_layout,6,0,1,4)
217
+
218
+ # def refresh_signal_models(self):
219
+ # signal_models = get_signal_models_list()
220
+ # self.signal_models_list.clear()
221
+ # self.signal_models_list.addItems(signal_models)
222
+
223
+ # def generate_tracking_options(self):
224
+ # grid_track = QHBoxLayout()
225
+
226
+ # self.track_action = QCheckBox("TRACK")
227
+ # self.track_action.setIcon(icon(MDI6.chart_timeline_variant,color="black"))
228
+ # self.track_action.setIconSize(QSize(20, 20))
229
+ # self.track_action.setToolTip("Track the target cells using bTrack.")
230
+ # self.track_action.setStyleSheet("""
231
+ # font-size: 10px;
232
+ # padding-left: 10px;
233
+ # padding-top: 5px;
234
+ # """)
235
+ # grid_track.addWidget(self.track_action, 80)
236
+ # #self.to_disable.append(self.track_action_tc)
237
+
238
+ # # self.show_track_table_btn = QPushButton()
239
+ # # self.show_track_table_btn.setIcon(icon(MDI6.table,color="black"))
240
+ # # self.show_track_table_btn.setIconSize(QSize(20, 20))
241
+ # # self.show_track_table_btn.setToolTip("Show trajectories table.")
242
+ # # self.show_track_table_btn.setStyleSheet(self.parent.parent.button_select_all)
243
+ # # #self.show_track_table_btn.clicked.connect(self.display_trajectory_table)
244
+ # # self.show_track_table_btn.setEnabled(False)
245
+ # # grid_track.addWidget(self.show_track_table_btn, 6) #4,3,1,1, alignment=Qt.AlignLeft
246
+
247
+ # self.check_tracking_result_btn = QPushButton()
248
+ # self.check_tracking_result_btn.setIcon(icon(MDI6.eye_check_outline,color="black"))
249
+ # self.check_tracking_result_btn.setIconSize(QSize(20, 20))
250
+ # self.check_tracking_result_btn.setToolTip("Control dynamically the trajectories.")
251
+ # self.check_tracking_result_btn.setStyleSheet(self.parent.parent.button_select_all)
252
+ # self.check_tracking_result_btn.clicked.connect(self.open_napari_tracking)
253
+ # self.check_tracking_result_btn.setEnabled(False)
254
+ # grid_track.addWidget(self.check_tracking_result_btn, 6) #4,3,1,1, alignment=Qt.AlignLeft
255
+
256
+ # self.track_config_btn = QPushButton()
257
+ # self.track_config_btn.setIcon(icon(MDI6.cog_outline,color="black"))
258
+ # self.track_config_btn.setIconSize(QSize(20, 20))
259
+ # self.track_config_btn.setToolTip("Configure tracking.")
260
+ # self.track_config_btn.setStyleSheet(self.parent.parent.button_select_all)
261
+ # self.track_config_btn.clicked.connect(self.open_tracking_configuration_ui)
262
+ # grid_track.addWidget(self.track_config_btn, 6) #4,2,1,1, alignment=Qt.AlignRight
263
+
264
+ # self.grid_contents.addLayout(grid_track, 4, 0, 1,4)
265
+
266
+
267
+ # def generate_segmentation_options(self):
268
+
269
+ # grid_segment = QHBoxLayout()
270
+ # grid_segment.setContentsMargins(0,0,0,0)
271
+ # grid_segment.setSpacing(0)
272
+
273
+ # self.segment_action = QCheckBox("SEGMENT")
274
+ # self.segment_action.setStyleSheet("""
275
+ # font-size: 10px;
276
+ # padding-left: 10px;
277
+ # """)
278
+ # self.segment_action.setIcon(icon(MDI6.bacteria, color='black'))
279
+ # self.segment_action.setToolTip("Segment the cells in the movie\nusing the selected pre-trained model and save\nthe labeled output in a sub-directory.")
280
+ # self.segment_action.toggled.connect(self.enable_segmentation_model_list)
281
+ # #self.to_disable.append(self.segment_action)
282
+ # grid_segment.addWidget(self.segment_action, 90)
283
+
284
+ # self.check_seg_btn = QPushButton()
285
+ # self.check_seg_btn.setIcon(icon(MDI6.eye_check_outline,color="black"))
286
+ # self.check_seg_btn.setIconSize(QSize(20, 20))
287
+ # self.check_seg_btn.clicked.connect(self.check_segmentation)
288
+ # self.check_seg_btn.setStyleSheet(self.parent.parent.button_select_all)
289
+ # self.check_seg_btn.setEnabled(False)
290
+ # #self.to_disable.append(self.control_target_seg)
291
+ # grid_segment.addWidget(self.check_seg_btn, 10)
292
+ # self.grid_contents.addLayout(grid_segment, 0,0,1,4)
293
+
294
+ # model_zoo_layout = QHBoxLayout()
295
+ # model_zoo_layout.addWidget(QLabel("Model zoo:"),90)
296
+ # self.seg_model_list = QComboBox()
297
+ # #self.to_disable.append(self.tc_seg_model_list)
298
+ # self.seg_model_list.setGeometry(50, 50, 200, 30)
299
+ # self.init_seg_model_list()
300
+
301
+
302
+ # self.upload_model_btn = QPushButton("UPLOAD")
303
+ # self.upload_model_btn.setIcon(icon(MDI6.upload,color="black"))
304
+ # self.upload_model_btn.setIconSize(QSize(20, 20))
305
+ # self.upload_model_btn.setStyleSheet(self.parent.parent.button_style_sheet_3)
306
+ # self.upload_model_btn.setToolTip("Upload a new segmentation model (Deep learning or threshold-based).")
307
+ # model_zoo_layout.addWidget(self.upload_model_btn, 5)
308
+ # self.upload_model_btn.clicked.connect(self.upload_segmentation_model)
309
+ # # self.to_disable.append(self.upload_tc_model)
310
+
311
+ # self.train_btn = QPushButton("TRAIN")
312
+ # self.train_btn.setToolTip("Train or retrain a segmentation model on newly annotated data.")
313
+ # self.train_btn.setIcon(icon(MDI6.redo_variant,color='black'))
314
+ # self.train_btn.setIconSize(QSize(20, 20))
315
+ # self.train_btn.setStyleSheet(self.parent.parent.button_style_sheet_3)
316
+ # model_zoo_layout.addWidget(self.train_btn, 5)
317
+ # # self.train_button_tc.clicked.connect(self.train_stardist_model_tc)
318
+ # # self.to_disable.append(self.train_button_tc)
319
+
320
+ # self.grid_contents.addLayout(model_zoo_layout, 2, 0, 1,4)
321
+ # self.seg_model_list.setEnabled(False)
322
+ # self.grid_contents.addWidget(self.seg_model_list, 3, 0, 1, 4)
323
+
324
+ # def check_segmentation(self):
325
+
326
+ # #self.freeze()
327
+ # #QApplication.setOverrideCursor(Qt.WaitCursor)
328
+ # test = self.parent.locate_selected_position()
329
+ # if test:
330
+ # control_segmentation_napari(self.parent.pos, prefix=self.parent.movie_prefix, population=self.mode,flush_memory=True)
331
+ # gc.collect()
332
+
333
+ # def check_signals(self):
334
+
335
+ # test = self.parent.locate_selected_position()
336
+ # if test:
337
+ # self.SignalAnnotator = SignalAnnotator(self)
338
+ # self.SignalAnnotator.show()
339
+
340
+
341
+ # def enable_segmentation_model_list(self):
342
+ # if self.segment_action.isChecked():
343
+ # self.seg_model_list.setEnabled(True)
344
+ # else:
345
+ # self.seg_model_list.setEnabled(False)
346
+
347
+ # def enable_signal_model_list(self):
348
+ # if self.signal_analysis_action.isChecked():
349
+ # self.signal_models_list.setEnabled(True)
350
+ # else:
351
+ # self.signal_models_list.setEnabled(False)
352
+
353
+ # def init_seg_model_list(self):
354
+
355
+ # self.seg_model_list.clear()
356
+ # self.seg_models = get_segmentation_models_list(mode=self.mode, return_path=False)
357
+ # self.seg_models.insert(0,'Threshold')
358
+ # thresh = 40
359
+ # models_truncated = [m[:thresh - 3]+'...' if len(m)>thresh else m for m in self.seg_models]
360
+ # self.seg_model_list.addItems(models_truncated)
361
+ # for i in range(len(self.seg_models)):
362
+ # self.seg_model_list.setItemData(i, self.seg_models[i], Qt.ToolTipRole)
363
+
364
+
365
+ # #if ("live_nuclei_channel" in self.exp_channels)*("dead_nuclei_channel" in self.exp_channels):
366
+ # # print("both channels found")
367
+ # # index = self.tc_seg_model_list.findText("MCF7_Hoescht_PI_w_primary_NK", Qt.MatchFixedString)
368
+ # # if index >= 0:
369
+ # # self.tc_seg_model_list.setCurrentIndex(index)
370
+ # # elif ("live_nuclei_channel" in self.exp_channels)*("dead_nuclei_channel" not in self.exp_channels):
371
+ # # index = self.tc_seg_model_list.findText("MCF7_Hoescht_w_primary_NK", Qt.MatchFixedString)
372
+ # # if index >= 0:
373
+ # # self.tc_seg_model_list.setCurrentIndex(index)
374
+ # # elif ("live_nuclei_channel" not in self.exp_channels)*("dead_nuclei_channel" in self.exp_channels):
375
+ # # index = self.tc_seg_model_list.findText("MCF7_PI_w_primary_NK", Qt.MatchFixedString)
376
+ # # if index >= 0:
377
+ # # self.tc_seg_model_list.setCurrentIndex(index)
378
+ # # elif ("live_nuclei_channel" not in self.exp_channels)*("dead_nuclei_channel" not in self.exp_channels)*("adhesion_channel" in self.exp_channels):
379
+ # # index = self.tc_seg_model_list.findText("RICM", Qt.MatchFixedString)
380
+ # # if index >= 0:
381
+ # # self.tc_seg_model_list.setCurrentIndex(index)
382
+
383
+ # def tick_all_actions(self):
384
+ # self.switch_all_ticks_option()
385
+ # if self.all_ticked:
386
+ # self.select_all_btn.setIcon(icon(MDI6.checkbox_outline,color="black"))
387
+ # self.select_all_btn.setIconSize(QSize(20, 20))
388
+ # self.segment_action.setChecked(True)
389
+ # else:
390
+ # self.select_all_btn.setIcon(icon(MDI6.checkbox_blank_outline,color="black"))
391
+ # self.select_all_btn.setIconSize(QSize(20, 20))
392
+ # self.segment_action.setChecked(False)
393
+
394
+ # def switch_all_ticks_option(self):
395
+ # if self.all_ticked == True:
396
+ # self.all_ticked = False
397
+ # else:
398
+ # self.all_ticked = True
399
+
400
+ # def upload_segmentation_model(self):
401
+
402
+ # self.SegModelLoader = SegmentationModelLoader(self)
403
+ # self.SegModelLoader.show()
404
+
405
+ # def open_tracking_configuration_ui(self):
406
+
407
+ # self.ConfigTracking = ConfigTracking(self)
408
+ # self.ConfigTracking.show()
409
+
410
+ # def open_signal_model_config_ui(self):
411
+
412
+ # self.ConfigSignalTrain = ConfigSignalModelTraining(self)
413
+ # self.ConfigSignalTrain.show()
414
+
415
+ # def open_measurement_configuration_ui(self):
416
+
417
+ # self.ConfigMeasurements = ConfigMeasurements(self)
418
+ # self.ConfigMeasurements.show()
419
+
420
+ # def open_signal_annotator_configuration_ui(self):
421
+ # self.ConfigSignalAnnotator = ConfigSignalAnnotator(self)
422
+ # self.ConfigSignalAnnotator.show()
423
+
424
+ # def process_population(self):
425
+
426
+ # if self.parent.well_list.currentText()=="*":
427
+ # self.well_index = np.linspace(0,len(self.wells)-1,len(self.wells),dtype=int)
428
+ # else:
429
+ # self.well_index = [self.parent.well_list.currentIndex()]
430
+ # print(f"Processing well {self.parent.well_list.currentText()}...")
431
+
432
+ # # self.freeze()
433
+ # # QApplication.setOverrideCursor(Qt.WaitCursor)
434
+
435
+ # if self.mode=="targets":
436
+ # self.threshold_config = self.threshold_config_targets
437
+ # elif self.mode=="effectors":
438
+ # self.threshold_config = self.threshold_config_effectors
439
+
440
+ # loop_iter=0
441
+
442
+ # if self.parent.position_list.currentText()=="*":
443
+ # msgBox = QMessageBox()
444
+ # msgBox.setIcon(QMessageBox.Question)
445
+ # msgBox.setText("If you continue, all positions will be processed.\nDo you want to proceed?")
446
+ # msgBox.setWindowTitle("Info")
447
+ # msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
448
+ # returnValue = msgBox.exec()
449
+ # if returnValue == QMessageBox.No:
450
+ # return None
451
+
452
+ # for w_idx in self.well_index:
453
+
454
+ # pos = self.parent.positions[w_idx]
455
+ # if self.parent.position_list.currentText()=="*":
456
+ # pos_indices = np.linspace(0,len(pos)-1,len(pos),dtype=int)
457
+ # print("Processing all positions...")
458
+ # else:
459
+ # pos_indices = natsorted([pos.index(self.parent.position_list.currentText())])
460
+ # print(f"Processing position {self.parent.position_list.currentText()}...")
461
+
462
+ # well = self.parent.wells[w_idx]
463
+
464
+ # for pos_idx in pos_indices:
465
+
466
+ # self.pos = natsorted(glob(well+f"{well[-2]}*/"))[pos_idx]
467
+ # print(f"Position {self.pos}...\nLoading stack movie...")
468
+ # model_name = self.seg_models[self.seg_model_list.currentIndex()]
469
+
470
+ # if not os.path.exists(self.pos + 'output/'):
471
+ # os.mkdir(self.pos + 'output/')
472
+ # if not os.path.exists(self.pos + 'output/tables/'):
473
+ # os.mkdir(self.pos + 'output/tables/')
474
+
475
+ # if self.segment_action.isChecked():
476
+
477
+ # if len(glob(os.sep.join([self.pos, f'labels_{self.mode}','*.tif'])))>0 and self.parent.position_list.currentText()!="*":
478
+ # msgBox = QMessageBox()
479
+ # msgBox.setIcon(QMessageBox.Question)
480
+ # msgBox.setText("Labels have already been produced for this position. Do you want to segment again?")
481
+ # msgBox.setWindowTitle("Info")
482
+ # msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
483
+ # returnValue = msgBox.exec()
484
+ # if returnValue == QMessageBox.No:
485
+ # return None
486
+
487
+ # if (self.seg_model_list.currentText()=="Threshold"):
488
+ # if self.threshold_config is None:
489
+ # msgBox = QMessageBox()
490
+ # msgBox.setIcon(QMessageBox.Warning)
491
+ # msgBox.setText("Please set a threshold configuration from the upload menu first. Abort.")
492
+ # msgBox.setWindowTitle("Warning")
493
+ # msgBox.setStandardButtons(QMessageBox.Ok)
494
+ # returnValue = msgBox.exec()
495
+ # if returnValue == QMessageBox.Ok:
496
+ # return None
497
+ # else:
498
+ # print(f"Segmentation from threshold config: {self.threshold_config}")
499
+ # segment_from_threshold_at_position(self.pos, self.mode, self.threshold_config)
500
+ # else:
501
+ # segment_at_position(self.pos, self.mode, model_name, stack_prefix=self.parent.movie_prefix, use_gpu=True)
502
+
503
+ # if self.track_action.isChecked():
504
+ # if os.path.exists(os.sep.join([self.pos, 'output', 'tables', f'trajectories_{self.mode}.csv'])) and self.parent.position_list.currentText()!="*":
505
+ # msgBox = QMessageBox()
506
+ # msgBox.setIcon(QMessageBox.Question)
507
+ # msgBox.setText("A trajectory set already exists. Previously annotated data for\nthis position will be lost. Do you want to proceed?")
508
+ # msgBox.setWindowTitle("Info")
509
+ # msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
510
+ # returnValue = msgBox.exec()
511
+ # if returnValue == QMessageBox.No:
512
+ # return None
513
+ # track_at_position(self.pos, self.mode)
514
+
515
+ # if self.measure_action.isChecked():
516
+ # measure_at_position(self.pos, self.mode)
517
+
518
+ # table = os.sep.join([self.pos, 'output', 'tables', f'trajectories_{self.mode}.csv'])
519
+ # if self.signal_analysis_action.isChecked() and os.path.exists(table):
520
+ # print('table exists')
521
+ # table = pd.read_csv(table)
522
+ # cols = list(table.columns)
523
+ # print(table, cols)
524
+ # if 'class_color' in cols:
525
+ # print(cols, 'class_color in cols')
526
+ # colors = list(table['class_color'].to_numpy())
527
+ # if 'tab:orange' in colors or 'tab:cyan' in colors:
528
+ # if self.parent.position_list.currentText()!="*":
529
+ # msgBox = QMessageBox()
530
+ # msgBox.setIcon(QMessageBox.Question)
531
+ # msgBox.setText("The signals of the cells in the position appear to have been annotated... Do you want to proceed?")
532
+ # msgBox.setWindowTitle("Info")
533
+ # msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
534
+ # returnValue = msgBox.exec()
535
+ # if returnValue == QMessageBox.No:
536
+ # return None
537
+ # analyze_signals_at_position(self.pos, self.signal_models_list.currentText(), self.mode)
538
+
539
+
540
+ # # self.stack = None
541
+ # self.parent.update_position_options()
542
+ # if self.segment_action.isChecked():
543
+ # self.segment_action.setChecked(False)
544
+
545
+ # # QApplication.restoreOverrideCursor()
546
+ # # self.unfreeze()
547
+
548
+ # def open_napari_tracking(self):
549
+ # control_tracking_btrack(self.parent.pos, prefix=self.parent.movie_prefix, population=self.mode)
550
+
551
+ # def view_table_ui(self):
552
+ # print('view table')
553
+
554
+ # test = self.parent.locate_selected_position()
555
+ # if test:
556
+ # tab_path = os.sep.join([self.parent.pos,"output","tables",f"trajectories_{self.mode}.csv"])
557
+ # print(tab_path)
558
+ # if os.path.exists(tab_path):
559
+ # trajectories = pd.read_csv(tab_path)
560
+ # self.tab_ui = TableUI(trajectories, f"Tracks {self.parent.position_list.currentText()}")
561
+ # self.tab_ui.show()
562
+ # else:
563
+ # print(test, 'test failed')