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,438 @@
1
+ from PyQt5.QtWidgets import QMainWindow, QComboBox, QPushButton, QHBoxLayout, QLabel, QWidget, QGridLayout, QFrame, \
2
+ QTabWidget, QVBoxLayout, QMessageBox, QScrollArea, QDesktopWidget
3
+ from PyQt5.QtCore import Qt, QSize
4
+ from PyQt5.QtGui import QIcon
5
+ from celldetective.gui.gui_utils import center_window, QHSeperationLine
6
+ from celldetective.utils import _extract_labels_from_config, ConfigSectionMap, extract_experiment_channels
7
+ from celldetective.gui import ConfigEditor, ProcessPanel, AnalysisPanel, NeighPanel
8
+ from natsort import natsorted
9
+ from glob import glob
10
+ import os
11
+ import numpy as np
12
+ from superqt.fonticon import icon
13
+ from fonticon_mdi6 import MDI6
14
+ import gc
15
+ import subprocess
16
+
17
+ class ControlPanel(QMainWindow):
18
+
19
+ def __init__(self, parent=None, exp_dir=""):
20
+
21
+ super().__init__()
22
+ self.exp_dir = exp_dir
23
+ if not self.exp_dir.endswith(os.sep):
24
+ self.exp_dir = self.exp_dir+os.sep
25
+ self.setWindowTitle("celldetective")
26
+ self.setWindowIcon(QIcon(os.sep.join(['celldetective','icons','logo.png'])))
27
+ self.parent = parent
28
+ center_window(self)
29
+
30
+ self.init_wells_and_positions()
31
+ self.load_configuration()
32
+
33
+ self.w = QWidget()
34
+ self.grid = QGridLayout(self.w)
35
+ self.grid.setSpacing(5)
36
+ self.grid.setContentsMargins(20,20,20,20) #left top right bottom
37
+
38
+ self.to_disable = []
39
+ self.generate_header()
40
+ self.ProcessEffectors = ProcessPanel(self,'effectors')
41
+ self.ProcessTargets = ProcessPanel(self,'targets')
42
+ self.NeighPanel = NeighPanel(self)
43
+
44
+ ProcessFrame = QFrame()
45
+ grid_process = QVBoxLayout(ProcessFrame)
46
+ grid_process.setContentsMargins(20,50,20,20)
47
+
48
+ AnalyzeFrame = QFrame()
49
+ grid_analyze = QVBoxLayout(AnalyzeFrame)
50
+ grid_analyze.setContentsMargins(20,50,20,20)
51
+ self.SurvivalBlock = AnalysisPanel(self,title='Survival')
52
+
53
+
54
+ grid_process.addWidget(self.ProcessEffectors)
55
+ grid_process.addWidget(self.ProcessTargets)
56
+ grid_process.addWidget(self.NeighPanel)
57
+ grid_analyze.addWidget(self.SurvivalBlock)
58
+
59
+ self.scroll=QScrollArea()
60
+ self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
61
+ self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
62
+ self.scroll.setWidgetResizable(True)
63
+ desktop = QDesktopWidget()
64
+ self.scroll.setMinimumHeight(500)
65
+ #self.scroll.setMinimumHeight(int(0.4*screen_height))
66
+
67
+ tabWidget = QTabWidget()
68
+ tab_index_process = tabWidget.addTab(ProcessFrame, "Process")
69
+ tabWidget.setTabIcon(tab_index_process, icon(MDI6.cog_outline, color='black'))
70
+
71
+ tab_index_analyze = tabWidget.addTab(AnalyzeFrame, "Analyze")
72
+ tabWidget.setTabIcon(tab_index_analyze, icon(MDI6.poll, color='black'))
73
+ tabWidget.setStyleSheet(self.parent.qtab_style)
74
+
75
+ self.grid.addWidget(tabWidget, 7,0,1,3, alignment=Qt.AlignTop)
76
+ self.grid.setSpacing(5)
77
+ self.scroll.setWidget(self.w)
78
+ self.setCentralWidget(self.scroll)
79
+ self.create_config_dir()
80
+ self.update_position_options()
81
+ #self.setMinimumHeight(int(self.sizeHint().height()))
82
+
83
+ self.initial_height = self.size().height()
84
+ self.initial_width = self.size().width()
85
+ self.screen_height = desktop.screenGeometry().height()
86
+ self.screen_width = desktop.screenGeometry().width()
87
+ self.scroll.setMinimumWidth(410)
88
+
89
+ def init_wells_and_positions(self):
90
+
91
+ """
92
+ Detect the wells in the experiment folder and the associated positions.
93
+ """
94
+
95
+ self.wells = natsorted(glob(self.exp_dir + "W*" + os.sep))
96
+ self.positions = []
97
+ for w in self.wells:
98
+ w = os.path.split(w[:-1])
99
+ root = w[0]
100
+ w = w[1]
101
+ positions_path = natsorted(glob(os.sep.join([root, w, f"{w[1:]}*{os.sep}"])))
102
+ self.positions.append([os.path.split(pos[:-1])[1] for pos in positions_path])
103
+
104
+ def generate_header(self):
105
+
106
+ """
107
+ Show the experiment name, create two QComboBox for respectively the
108
+ biological condition (well) and position of interest, access the experiment config.
109
+ """
110
+
111
+ condition_label = QLabel("condition: ")
112
+ position_label = QLabel("position: ")
113
+
114
+ name = self.exp_dir.split(os.sep)[-2]
115
+ experiment_label = QLabel(f"Experiment:")
116
+ experiment_label.setStyleSheet("""
117
+ font-weight: bold;
118
+ """)
119
+
120
+ self.folder_exp_btn = QPushButton()
121
+ self.folder_exp_btn.setIcon(icon(MDI6.folder,color="black"))
122
+ self.folder_exp_btn.setIconSize(QSize(20, 20))
123
+ self.folder_exp_btn.setToolTip("Experiment folder")
124
+ self.folder_exp_btn.clicked.connect(self.open_experiment_folder)
125
+ self.folder_exp_btn.setStyleSheet(self.parent.button_select_all)
126
+
127
+
128
+ self.edit_config_button = QPushButton()
129
+ self.edit_config_button.setIcon(icon(MDI6.cog_outline,color="black"))
130
+ self.edit_config_button.setIconSize(QSize(20, 20))
131
+ self.edit_config_button.setToolTip("Configuration file")
132
+ self.edit_config_button.clicked.connect(self.open_config_editor)
133
+ self.edit_config_button.setStyleSheet(self.parent.button_select_all)
134
+
135
+ self.exp_options_layout = QHBoxLayout()
136
+ self.exp_options_layout.addWidget(experiment_label, 32, alignment=Qt.AlignRight)
137
+ self.exp_options_layout.addWidget(QLabel(name), 65, alignment=Qt.AlignLeft)
138
+ self.exp_options_layout.addWidget(self.folder_exp_btn, 5, alignment=Qt.AlignRight)
139
+ self.exp_options_layout.addWidget(self.edit_config_button, 5, alignment=Qt.AlignRight)
140
+ self.grid.addLayout(self.exp_options_layout, 0,0,1,3)
141
+
142
+ self.well_list = QComboBox()
143
+ thresh = 40
144
+ self.well_truncated = [w[:thresh - 3]+'...' if len(w)>thresh else w for w in self.well_labels]
145
+ self.well_list.addItems(self.well_truncated) #self.well_labels
146
+ for i in range(len(self.well_labels)):
147
+ self.well_list.setItemData(i, self.well_labels[i], Qt.ToolTipRole)
148
+ self.well_list.addItems(["*"])
149
+ self.well_list.activated.connect(self.display_positions)
150
+ self.to_disable.append(self.well_list)
151
+
152
+ self.position_list = QComboBox()
153
+ self.position_list.addItems(["*"])
154
+ self.position_list.addItems(self.positions[0])
155
+ self.position_list.activated.connect(self.update_position_options)
156
+ self.to_disable.append(self.position_list)
157
+ #self.locate_selected_position()
158
+
159
+ self.grid.addWidget(QLabel("Well:"), 1, 0, 1,1, alignment=Qt.AlignRight)
160
+ self.grid.addWidget(self.well_list, 1, 1, 1, 2)
161
+
162
+ self.grid.addWidget(QLabel("Position:"),2,0,1,1, alignment=Qt.AlignRight)
163
+ self.grid.addWidget(self.position_list, 2,1,1,2)
164
+
165
+
166
+ hsep = QHSeperationLine()
167
+ self.grid.addWidget(hsep, 5, 0, 1, 3)
168
+
169
+ def open_experiment_folder(self):
170
+
171
+ try:
172
+ subprocess.Popen(f'explorer {os.path.realpath(self.exp_dir)}')
173
+ except:
174
+ try:
175
+ os.system('xdg-open "%s"' % self.exp_dir)
176
+ except:
177
+ return None
178
+
179
+ def load_configuration(self):
180
+
181
+ '''
182
+ This methods load the configuration read in the config.ini file of the experiment.
183
+ '''
184
+
185
+ self.exp_config = self.exp_dir + "config.ini"
186
+ self.PxToUm = float(ConfigSectionMap(self.exp_config,"MovieSettings")["pxtoum"])
187
+ self.FrameToMin = float(ConfigSectionMap(self.exp_config,"MovieSettings")["frametomin"])
188
+ self.len_movie = int(ConfigSectionMap(self.exp_config,"MovieSettings")["len_movie"])
189
+ self.shape_x = int(ConfigSectionMap(self.exp_config,"MovieSettings")["shape_x"])
190
+ self.shape_y = int(ConfigSectionMap(self.exp_config,"MovieSettings")["shape_y"])
191
+ self.movie_prefix = ConfigSectionMap(self.exp_config,"MovieSettings")["movie_prefix"]
192
+
193
+ # Read channels
194
+ self.exp_channels, channel_indices = extract_experiment_channels(self.exp_config)
195
+ self.nbr_channels = len(self.exp_channels)
196
+
197
+ number_of_wells = len(self.wells)
198
+ self.well_labels = _extract_labels_from_config(self.exp_config,number_of_wells)
199
+
200
+ self.concentrations = ConfigSectionMap(self.exp_config,"Labels")["concentrations"].split(",")
201
+ if number_of_wells != len(self.concentrations):
202
+ self.concentrations = [str(s) for s in np.linspace(0,number_of_wells-1,number_of_wells)]
203
+
204
+ #self.antibodies = extract_labels_from_config(config, number_of_wells)
205
+
206
+ self.cell_types = ConfigSectionMap(self.exp_config,"Labels")["cell_types"].split(",")
207
+ if number_of_wells != len(self.cell_types):
208
+ self.cell_types = [str(s) for s in np.linspace(0,number_of_wells-1,number_of_wells)]
209
+
210
+ try:
211
+ self.antibodies = ConfigSectionMap(self.exp_config,"Labels")["antibodies"].split(",")
212
+ if number_of_wells != len(self.antibodies):
213
+ self.antibodies = [str(s) for s in np.linspace(0,number_of_wells-1,number_of_wells)]
214
+ except:
215
+ print("Warning... antibodies not found...")
216
+ self.antibodies = [str(s) for s in np.linspace(0,number_of_wells-1,number_of_wells)]
217
+
218
+ try:
219
+ self.pharmaceutical_agents = ConfigSectionMap(self.exp_config,"Labels")["pharmaceutical_agents"].split(",")
220
+ if number_of_wells != len(self.pharmaceutical_agents):
221
+ self.pharmaceutical_agents = [str(s) for s in np.linspace(0,number_of_wells-1,number_of_wells)]
222
+ except:
223
+ print("Warning... pharmaceutical agents not found...")
224
+ self.pharmaceutical_agents = [str(s) for s in np.linspace(0,number_of_wells-1,number_of_wells)]
225
+
226
+
227
+ def closeEvent(self, event):
228
+
229
+ """
230
+ Close child windows if closed.
231
+ """
232
+
233
+ try:
234
+ if self.cfg_editor:
235
+ self.cfg_editor.close()
236
+ except:
237
+ pass
238
+
239
+ try:
240
+ if self.ProcessTargets.SegModelLoader:
241
+ self.ProcessTargets.SegModelLoader.close()
242
+ except:
243
+ pass
244
+
245
+ try:
246
+ if self.ProcessEffectors.SegModelLoader:
247
+ self.ProcessEffectors.SegModelLoader.close()
248
+ except:
249
+ pass
250
+
251
+ try:
252
+ if self.ProcessTargets.ConfigTracking:
253
+ self.ProcessTargets.ConfigTracking.close()
254
+ except:
255
+ pass
256
+
257
+ try:
258
+ if self.ProcessEffectors.ConfigTracking:
259
+ self.ProcessEffectors.ConfigTracking.close()
260
+ except:
261
+ pass
262
+
263
+ try:
264
+ if self.ProcessTargets.ConfigSignalTrain:
265
+ self.ProcessTargets.ConfigSignalTrain.close()
266
+ except:
267
+ pass
268
+
269
+ try:
270
+ if self.ProcessEffectors.ConfigSignalTrain:
271
+ self.ProcessEffectors.ConfigSignalTrain.close()
272
+ except:
273
+ pass
274
+
275
+ try:
276
+ if self.ProcessTargets.ConfigMeasurements:
277
+ self.ProcessTargets.ConfigMeasurements.close()
278
+ except:
279
+ pass
280
+
281
+ try:
282
+ if self.ProcessEffectors.ConfigMeasurements:
283
+ self.ProcessEffectors.ConfigMeasurements.close()
284
+ except:
285
+ pass
286
+
287
+ try:
288
+ if self.ProcessTargets.ConfigSignalAnnotator:
289
+ self.ProcessTargets.ConfigSignalAnnotator.close()
290
+ except:
291
+ pass
292
+
293
+ try:
294
+ if self.ProcessEffectors.ConfigSignalAnnotator:
295
+ self.ProcessEffectors.ConfigSignalAnnotator.close()
296
+ except:
297
+ pass
298
+
299
+ gc.collect()
300
+
301
+
302
+ def display_positions(self):
303
+
304
+ """
305
+ Show the positions as the well is changed.
306
+ """
307
+
308
+ if self.well_list.currentText()=="*":
309
+ self.position_list.clear()
310
+ self.position_list.addItems(["*"])
311
+ position_linspace = np.linspace(0,len(self.positions[0])-1,len(self.positions[0]),dtype=int)
312
+ position_linspace = [str(s) for s in position_linspace]
313
+ self.position_list.addItems(position_linspace)
314
+ else:
315
+ pos_index = self.well_list.currentIndex()
316
+ self.position_list.clear()
317
+ self.position_list.addItems(["*"])
318
+ self.position_list.addItems(self.positions[pos_index])
319
+
320
+ def open_config_editor(self):
321
+ self.cfg_editor = ConfigEditor(self)
322
+ self.cfg_editor.show()
323
+
324
+ def locate_selected_position(self):
325
+
326
+ """
327
+ Set the current position if the option one well, one positon is selected
328
+ Display error messages otherwise.
329
+
330
+ """
331
+
332
+ if self.well_list.currentText()=="*":
333
+ msgBox = QMessageBox()
334
+ msgBox.setIcon(QMessageBox.Critical)
335
+ msgBox.setText("Please select a single well...")
336
+ msgBox.setWindowTitle("Error")
337
+ msgBox.setStandardButtons(QMessageBox.Ok)
338
+ returnValue = msgBox.exec()
339
+ if returnValue == QMessageBox.Ok:
340
+ return False
341
+ else:
342
+ self.well_index = [self.well_list.currentIndex()]
343
+
344
+ for w_idx in self.well_index:
345
+
346
+ pos = self.positions[w_idx]
347
+ if self.position_list.currentText()=="*":
348
+ msgBox = QMessageBox()
349
+ msgBox.setIcon(QMessageBox.Critical)
350
+ msgBox.setText("Please select a single position...")
351
+ msgBox.setWindowTitle("Error")
352
+ msgBox.setStandardButtons(QMessageBox.Ok)
353
+ returnValue = msgBox.exec()
354
+ if returnValue == QMessageBox.Ok:
355
+ return False
356
+ else:
357
+ pos_indices = natsorted([pos.index(self.position_list.currentText())])
358
+
359
+ well = self.wells[w_idx]
360
+
361
+ for pos_idx in pos_indices:
362
+ self.pos = natsorted(glob(well+f"{os.path.split(well)[-1].replace('W','').replace(os.sep,'')}*{os.sep}"))[pos_idx]
363
+ if not os.path.exists(self.pos + 'output'):
364
+ os.mkdir(self.pos + 'output')
365
+ if not os.path.exists(self.pos + os.sep.join(['output','tables'])):
366
+ os.mkdir(self.pos + os.sep.join(['output','tables']))
367
+
368
+ return True
369
+
370
+ def create_config_dir(self):
371
+ self.config_folder = self.exp_dir+'configs'+os.sep
372
+ if not os.path.exists(self.config_folder):
373
+ os.mkdir(self.config_folder)
374
+
375
+ def update_position_options(self):
376
+
377
+ self.pos = self.position_list.currentText()
378
+ panels = [self.ProcessEffectors, self.ProcessTargets]
379
+ if self.position_list.currentText()=="*":
380
+ for p in panels:
381
+ p.check_seg_btn.setEnabled(False)
382
+ p.check_tracking_result_btn.setEnabled(False)
383
+ self.ProcessTargets.view_tab_btn.setEnabled(True)
384
+ self.ProcessEffectors.view_tab_btn.setEnabled(True)
385
+ self.ProcessTargets.check_seg_btn.setEnabled(False)
386
+ self.ProcessEffectors.check_seg_btn.setEnabled(False)
387
+ self.ProcessTargets.check_tracking_result_btn.setEnabled(False)
388
+ self.ProcessEffectors.check_tracking_result_btn.setEnabled(False)
389
+ self.ProcessEffectors.check_measurements_btn.setEnabled(False)
390
+ self.ProcessTargets.check_measurements_btn.setEnabled(False)
391
+ #self.ProcessTargets.signal_analysis_action.setEnabled(False)
392
+ #self.ProcessEffectors.signal_analysis_action.setEnabled(False)
393
+ self.ProcessTargets.check_signals_btn.setEnabled(False)
394
+ self.ProcessEffectors.check_signals_btn.setEnabled(False)
395
+ elif self.well_list.currentText()=='*':
396
+ self.ProcessTargets.view_tab_btn.setEnabled(True)
397
+ self.ProcessEffectors.view_tab_btn.setEnabled(True)
398
+ else:
399
+ if not self.well_list.currentText()=="*":
400
+ self.locate_selected_position()
401
+ # if os.path.exists(os.sep.join([self.pos,'labels_effectors', os.sep])):
402
+ self.ProcessEffectors.check_seg_btn.setEnabled(True)
403
+ # if os.path.exists(os.sep.join([self.pos,'labels_targets', os.sep])):
404
+ self.ProcessTargets.check_seg_btn.setEnabled(True)
405
+
406
+ if os.path.exists(os.sep.join([self.pos,'output','tables','napari_target_trajectories.npy'])):
407
+ self.ProcessTargets.check_tracking_result_btn.setEnabled(True)
408
+ else:
409
+ self.ProcessTargets.check_tracking_result_btn.setEnabled(False)
410
+ if os.path.exists(os.sep.join([self.pos,'output','tables','napari_effector_trajectories.npy'])):
411
+ self.ProcessEffectors.check_tracking_result_btn.setEnabled(True)
412
+ else:
413
+ self.ProcessEffectors.check_tracking_result_btn.setEnabled(False)
414
+
415
+ if os.path.exists(os.sep.join([self.pos,'output','tables','trajectories_effectors.csv'])):
416
+ self.ProcessEffectors.check_measurements_btn.setEnabled(True)
417
+ self.ProcessEffectors.check_signals_btn.setEnabled(True)
418
+ #self.ProcessEffectors.signal_analysis_action.setEnabled(True)
419
+ self.ProcessEffectors.view_tab_btn.setEnabled(True)
420
+
421
+ else:
422
+ self.ProcessEffectors.check_measurements_btn.setEnabled(False)
423
+ self.ProcessEffectors.check_signals_btn.setEnabled(False)
424
+ #self.ProcessEffectors.signal_analysis_action.setEnabled(False)
425
+ self.ProcessEffectors.view_tab_btn.setEnabled(False)
426
+
427
+ if os.path.exists(os.sep.join([self.pos,'output','tables','trajectories_targets.csv'])):
428
+ self.ProcessTargets.check_measurements_btn.setEnabled(True)
429
+ self.ProcessTargets.check_signals_btn.setEnabled(True)
430
+ #self.ProcessTargets.signal_analysis_action.setEnabled(True)
431
+ self.ProcessTargets.view_tab_btn.setEnabled(True)
432
+
433
+ else:
434
+ self.ProcessTargets.check_measurements_btn.setEnabled(False)
435
+ self.ProcessTargets.check_signals_btn.setEnabled(False)
436
+ #self.ProcessTargets.signal_analysis_action.setEnabled(False)
437
+ self.ProcessTargets.view_tab_btn.setEnabled(False)
438
+