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.
- celldetective/__main__.py +7 -21
- celldetective/events.py +2 -44
- celldetective/extra_properties.py +62 -52
- celldetective/filters.py +4 -5
- celldetective/gui/__init__.py +1 -1
- celldetective/gui/analyze_block.py +37 -10
- celldetective/gui/btrack_options.py +24 -23
- celldetective/gui/classifier_widget.py +62 -19
- celldetective/gui/configure_new_exp.py +32 -35
- celldetective/gui/control_panel.py +120 -81
- celldetective/gui/gui_utils.py +674 -396
- celldetective/gui/json_readers.py +7 -6
- celldetective/gui/layouts.py +756 -0
- celldetective/gui/measurement_options.py +98 -513
- celldetective/gui/neighborhood_options.py +322 -270
- celldetective/gui/plot_measurements.py +1114 -0
- celldetective/gui/plot_signals_ui.py +21 -20
- celldetective/gui/process_block.py +449 -169
- celldetective/gui/retrain_segmentation_model_options.py +27 -26
- celldetective/gui/retrain_signal_model_options.py +25 -24
- celldetective/gui/seg_model_loader.py +31 -27
- celldetective/gui/signal_annotator.py +2326 -2295
- celldetective/gui/signal_annotator_options.py +18 -16
- celldetective/gui/styles.py +16 -1
- celldetective/gui/survival_ui.py +67 -39
- celldetective/gui/tableUI.py +337 -48
- celldetective/gui/thresholds_gui.py +75 -71
- celldetective/gui/viewers.py +743 -0
- celldetective/io.py +247 -27
- celldetective/measure.py +43 -263
- celldetective/models/segmentation_effectors/primNK_cfse/config_input.json +29 -0
- celldetective/models/segmentation_effectors/primNK_cfse/cp-cfse-transfer +0 -0
- celldetective/models/segmentation_effectors/primNK_cfse/training_instructions.json +37 -0
- celldetective/neighborhood.py +498 -27
- celldetective/preprocessing.py +1023 -0
- celldetective/scripts/analyze_signals.py +7 -0
- celldetective/scripts/measure_cells.py +12 -0
- celldetective/scripts/segment_cells.py +20 -4
- celldetective/scripts/track_cells.py +11 -0
- celldetective/scripts/train_segmentation_model.py +35 -34
- celldetective/segmentation.py +14 -9
- celldetective/signals.py +234 -329
- celldetective/tracking.py +2 -2
- celldetective/utils.py +602 -49
- celldetective-1.1.1.dist-info/METADATA +305 -0
- celldetective-1.1.1.dist-info/RECORD +84 -0
- {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/top_level.txt +1 -0
- tests/__init__.py +0 -0
- tests/test_events.py +28 -0
- tests/test_filters.py +24 -0
- tests/test_io.py +70 -0
- tests/test_measure.py +141 -0
- tests/test_neighborhood.py +70 -0
- tests/test_preprocessing.py +37 -0
- tests/test_segmentation.py +93 -0
- tests/test_signals.py +135 -0
- tests/test_tracking.py +164 -0
- tests/test_utils.py +118 -0
- celldetective-1.0.2.post1.dist-info/METADATA +0 -221
- celldetective-1.0.2.post1.dist-info/RECORD +0 -66
- {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/LICENSE +0 -0
- {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/WHEEL +0 -0
- {celldetective-1.0.2.post1.dist-info → celldetective-1.1.1.dist-info}/entry_points.txt +0 -0
|
@@ -21,22 +21,23 @@ from tifffile import imread
|
|
|
21
21
|
from pathlib import Path, PurePath
|
|
22
22
|
from datetime import datetime
|
|
23
23
|
from functools import partial
|
|
24
|
+
from celldetective.gui import Styles
|
|
24
25
|
|
|
25
|
-
class ConfigSegmentationModelTraining(QMainWindow):
|
|
26
|
+
class ConfigSegmentationModelTraining(QMainWindow, Styles):
|
|
26
27
|
|
|
27
28
|
"""
|
|
28
29
|
UI to set segmentation model training instructions.
|
|
29
30
|
|
|
30
31
|
"""
|
|
31
32
|
|
|
32
|
-
def __init__(self,
|
|
33
|
+
def __init__(self, parent_window=None):
|
|
33
34
|
|
|
34
35
|
super().__init__()
|
|
35
|
-
self.
|
|
36
|
+
self.parent_window = parent_window
|
|
36
37
|
self.setWindowTitle("Train segmentation model")
|
|
37
38
|
self.setWindowIcon(QIcon(os.sep.join(['celldetective','icons','mexican-hat.png'])))
|
|
38
|
-
self.mode = self.
|
|
39
|
-
self.exp_dir = self.
|
|
39
|
+
self.mode = self.parent_window.mode
|
|
40
|
+
self.exp_dir = self.parent_window.exp_dir
|
|
40
41
|
self.soft_path = get_software_location()
|
|
41
42
|
self.pretrained_model = None
|
|
42
43
|
self.dataset_folder = None
|
|
@@ -45,7 +46,7 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
45
46
|
self.onlyFloat = QDoubleValidator()
|
|
46
47
|
self.onlyInt = QIntValidator()
|
|
47
48
|
|
|
48
|
-
self.screen_height = self.
|
|
49
|
+
self.screen_height = self.parent_window.parent_window.parent_window.screen_height
|
|
49
50
|
center_window(self)
|
|
50
51
|
|
|
51
52
|
self.setMinimumWidth(500)
|
|
@@ -64,30 +65,30 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
64
65
|
# Create button widget and layout
|
|
65
66
|
self.scroll_area = QScrollArea(self)
|
|
66
67
|
self.button_widget = QWidget()
|
|
67
|
-
main_layout = QVBoxLayout()
|
|
68
|
-
self.button_widget.setLayout(main_layout)
|
|
69
|
-
main_layout.setContentsMargins(30,30,30,30)
|
|
68
|
+
self.main_layout = QVBoxLayout()
|
|
69
|
+
self.button_widget.setLayout(self.main_layout)
|
|
70
|
+
self.main_layout.setContentsMargins(30,30,30,30)
|
|
70
71
|
|
|
71
72
|
# first frame for FEATURES
|
|
72
73
|
self.model_frame = QFrame()
|
|
73
74
|
self.model_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
74
75
|
self.populate_model_frame()
|
|
75
|
-
main_layout.addWidget(self.model_frame)
|
|
76
|
+
self.main_layout.addWidget(self.model_frame)
|
|
76
77
|
|
|
77
78
|
self.data_frame = QFrame()
|
|
78
79
|
self.data_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
79
80
|
self.populate_data_frame()
|
|
80
|
-
main_layout.addWidget(self.data_frame)
|
|
81
|
+
self.main_layout.addWidget(self.data_frame)
|
|
81
82
|
|
|
82
83
|
self.hyper_frame = QFrame()
|
|
83
84
|
self.hyper_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
84
85
|
self.populate_hyper_frame()
|
|
85
|
-
main_layout.addWidget(self.hyper_frame)
|
|
86
|
+
self.main_layout.addWidget(self.hyper_frame)
|
|
86
87
|
|
|
87
88
|
self.submit_btn = QPushButton('Train')
|
|
88
|
-
self.submit_btn.setStyleSheet(self.
|
|
89
|
+
self.submit_btn.setStyleSheet(self.button_style_sheet)
|
|
89
90
|
self.submit_btn.clicked.connect(self.prep_model)
|
|
90
|
-
main_layout.addWidget(self.submit_btn)
|
|
91
|
+
self.main_layout.addWidget(self.submit_btn)
|
|
91
92
|
self.submit_btn.setEnabled(False)
|
|
92
93
|
|
|
93
94
|
#self.populate_left_panel()
|
|
@@ -215,7 +216,7 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
215
216
|
self.cancel_dataset = QPushButton()
|
|
216
217
|
self.cancel_dataset.setIcon(icon(MDI6.close,color="black"))
|
|
217
218
|
self.cancel_dataset.clicked.connect(self.clear_dataset)
|
|
218
|
-
self.cancel_dataset.setStyleSheet(self.
|
|
219
|
+
self.cancel_dataset.setStyleSheet(self.button_select_all)
|
|
219
220
|
self.cancel_dataset.setIconSize(QSize(20, 20))
|
|
220
221
|
self.cancel_dataset.setVisible(False)
|
|
221
222
|
train_data_layout.addWidget(self.cancel_dataset, 5)
|
|
@@ -292,7 +293,7 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
292
293
|
self.cancel_pretrained = QPushButton()
|
|
293
294
|
self.cancel_pretrained.setIcon(icon(MDI6.close,color="black"))
|
|
294
295
|
self.cancel_pretrained.clicked.connect(self.clear_pretrained)
|
|
295
|
-
self.cancel_pretrained.setStyleSheet(self.
|
|
296
|
+
self.cancel_pretrained.setStyleSheet(self.button_select_all)
|
|
296
297
|
self.cancel_pretrained.setIconSize(QSize(20, 20))
|
|
297
298
|
self.cancel_pretrained.setVisible(False)
|
|
298
299
|
pretrained_layout.addWidget(self.cancel_pretrained, 5)
|
|
@@ -318,13 +319,13 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
318
319
|
|
|
319
320
|
self.normalization_mode_btns[i].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
|
|
320
321
|
self.normalization_mode_btns[i].setIconSize(QSize(20, 20))
|
|
321
|
-
self.normalization_mode_btns[i].setStyleSheet(self.
|
|
322
|
+
self.normalization_mode_btns[i].setStyleSheet(self.button_select_all)
|
|
322
323
|
self.normalization_mode_btns[i].setToolTip("Switch to absolute normalization values.")
|
|
323
324
|
self.normalization_mode_btns[i].clicked.connect(partial(self.switch_normalization_mode, i))
|
|
324
325
|
|
|
325
326
|
self.normalization_clip_btns[i].setIcon(icon(MDI6.content_cut,color="black"))
|
|
326
327
|
self.normalization_clip_btns[i].setIconSize(QSize(20, 20))
|
|
327
|
-
self.normalization_clip_btns[i].setStyleSheet(self.
|
|
328
|
+
self.normalization_clip_btns[i].setStyleSheet(self.button_select_all)
|
|
328
329
|
self.normalization_clip_btns[i].clicked.connect(partial(self.switch_clipping_mode, i))
|
|
329
330
|
self.normalization_clip_btns[i].setToolTip('clip')
|
|
330
331
|
|
|
@@ -337,7 +338,7 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
337
338
|
self.channel_items = ['--', 'brightfield_channel', 'live_nuclei_channel', 'dead_nuclei_channel',
|
|
338
339
|
'effector_fluo_channel', 'adhesion_channel', 'fluo_channel_1', 'fluo_channel_2','None'
|
|
339
340
|
]
|
|
340
|
-
exp_ch = self.
|
|
341
|
+
exp_ch = self.parent_window.parent_window.exp_channels
|
|
341
342
|
for c in exp_ch:
|
|
342
343
|
if c not in self.channel_items:
|
|
343
344
|
self.channel_items.append(c)
|
|
@@ -452,9 +453,9 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
452
453
|
|
|
453
454
|
def set_cellpose_scale(self):
|
|
454
455
|
|
|
455
|
-
scale = self.
|
|
456
|
+
scale = self.parent_window.parent_window.PxToUm * float(self.diameter_le.text()) / 30.0
|
|
456
457
|
if self.model_name=="CP_nuclei":
|
|
457
|
-
scale = self.
|
|
458
|
+
scale = self.parent_window.parent_window.PxToUm * float(self.diameter_le.text()) / 17.0
|
|
458
459
|
self.spatial_calib_le.setText(str(scale))
|
|
459
460
|
self.diamWidget.close()
|
|
460
461
|
|
|
@@ -647,7 +648,7 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
647
648
|
with open(model_folder+"training_instructions.json", 'w') as f:
|
|
648
649
|
json.dump(training_instructions, f, indent=4)
|
|
649
650
|
|
|
650
|
-
train_segmentation_model(model_folder+"training_instructions.json", use_gpu=self.
|
|
651
|
+
train_segmentation_model(model_folder+"training_instructions.json", use_gpu=self.parent_window.parent_window.parent_window.use_gpu)
|
|
651
652
|
|
|
652
653
|
# self.parent.refresh_signal_models()
|
|
653
654
|
|
|
@@ -673,7 +674,7 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
673
674
|
if self.normalization_mode[index]:
|
|
674
675
|
self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
|
|
675
676
|
self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
|
|
676
|
-
self.normalization_mode_btns[index].setStyleSheet(self.
|
|
677
|
+
self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
|
|
677
678
|
self.normalization_mode_btns[index].setToolTip("Switch to absolute normalization values.")
|
|
678
679
|
self.normalization_min_value_lbl[index].setText('Min %: ')
|
|
679
680
|
self.normalization_max_value_lbl[index].setText('Max %: ')
|
|
@@ -683,7 +684,7 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
683
684
|
else:
|
|
684
685
|
self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle_outline,color="black"))
|
|
685
686
|
self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
|
|
686
|
-
self.normalization_mode_btns[index].setStyleSheet(self.
|
|
687
|
+
self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
|
|
687
688
|
self.normalization_mode_btns[index].setToolTip("Switch to percentile normalization values.")
|
|
688
689
|
self.normalization_min_value_lbl[index].setText('Min: ')
|
|
689
690
|
self.normalization_min_value_le[index].setText('0')
|
|
@@ -698,9 +699,9 @@ class ConfigSegmentationModelTraining(QMainWindow):
|
|
|
698
699
|
if self.clip_option[index]:
|
|
699
700
|
self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="#1565c0"))
|
|
700
701
|
self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
|
|
701
|
-
self.normalization_clip_btns[index].setStyleSheet(self.
|
|
702
|
+
self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
|
|
702
703
|
|
|
703
704
|
else:
|
|
704
705
|
self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="black"))
|
|
705
706
|
self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
|
|
706
|
-
self.normalization_clip_btns[index].setStyleSheet(self.
|
|
707
|
+
self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
|
|
@@ -22,31 +22,32 @@ from pathlib import Path, PurePath
|
|
|
22
22
|
from datetime import datetime
|
|
23
23
|
import pandas as pd
|
|
24
24
|
from functools import partial
|
|
25
|
+
from celldetective.gui import Styles
|
|
25
26
|
|
|
26
|
-
class ConfigSignalModelTraining(QMainWindow):
|
|
27
|
+
class ConfigSignalModelTraining(QMainWindow, Styles):
|
|
27
28
|
|
|
28
29
|
"""
|
|
29
30
|
UI to set measurement instructions.
|
|
30
31
|
|
|
31
32
|
"""
|
|
32
33
|
|
|
33
|
-
def __init__(self,
|
|
34
|
+
def __init__(self, parent_window=None):
|
|
34
35
|
|
|
35
36
|
super().__init__()
|
|
36
|
-
self.
|
|
37
|
+
self.parent_window = parent_window
|
|
37
38
|
self.setWindowTitle("Train signal model")
|
|
38
39
|
self.setWindowIcon(QIcon(os.sep.join(['celldetective','icons','mexican-hat.png'])))
|
|
39
|
-
self.mode = self.
|
|
40
|
-
self.exp_dir = self.
|
|
40
|
+
self.mode = self.parent_window.mode
|
|
41
|
+
self.exp_dir = self.parent_window.exp_dir
|
|
41
42
|
self.soft_path = get_software_location()
|
|
42
43
|
self.pretrained_model = None
|
|
43
44
|
self.dataset_folder = None
|
|
44
|
-
self.signal_models_dir = self.soft_path+'
|
|
45
|
+
self.signal_models_dir = self.soft_path+os.sep+os.sep.join(['celldetective','models','signal_detection'])
|
|
45
46
|
|
|
46
47
|
self.onlyFloat = QDoubleValidator()
|
|
47
48
|
self.onlyInt = QIntValidator()
|
|
48
49
|
|
|
49
|
-
self.screen_height = self.
|
|
50
|
+
self.screen_height = self.parent_window.parent_window.parent_window.screen_height
|
|
50
51
|
center_window(self)
|
|
51
52
|
|
|
52
53
|
self.setMinimumWidth(500)
|
|
@@ -65,30 +66,30 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
65
66
|
# Create button widget and layout
|
|
66
67
|
self.scroll_area = QScrollArea(self)
|
|
67
68
|
self.button_widget = QWidget()
|
|
68
|
-
main_layout = QVBoxLayout()
|
|
69
|
-
self.button_widget.setLayout(main_layout)
|
|
70
|
-
main_layout.setContentsMargins(30,30,30,30)
|
|
69
|
+
self.main_layout = QVBoxLayout()
|
|
70
|
+
self.button_widget.setLayout(self.main_layout)
|
|
71
|
+
self.main_layout.setContentsMargins(30,30,30,30)
|
|
71
72
|
|
|
72
73
|
# first frame for FEATURES
|
|
73
74
|
self.model_frame = QFrame()
|
|
74
75
|
self.model_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
75
76
|
self.populate_model_frame()
|
|
76
|
-
main_layout.addWidget(self.model_frame)
|
|
77
|
+
self.main_layout.addWidget(self.model_frame)
|
|
77
78
|
|
|
78
79
|
self.data_frame = QFrame()
|
|
79
80
|
self.data_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
80
81
|
self.populate_data_frame()
|
|
81
|
-
main_layout.addWidget(self.data_frame)
|
|
82
|
+
self.main_layout.addWidget(self.data_frame)
|
|
82
83
|
|
|
83
84
|
self.hyper_frame = QFrame()
|
|
84
85
|
self.hyper_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
85
86
|
self.populate_hyper_frame()
|
|
86
|
-
main_layout.addWidget(self.hyper_frame)
|
|
87
|
+
self.main_layout.addWidget(self.hyper_frame)
|
|
87
88
|
|
|
88
89
|
self.submit_btn = QPushButton('Train')
|
|
89
|
-
self.submit_btn.setStyleSheet(self.
|
|
90
|
+
self.submit_btn.setStyleSheet(self.button_style_sheet)
|
|
90
91
|
self.submit_btn.clicked.connect(self.prep_model)
|
|
91
|
-
main_layout.addWidget(self.submit_btn)
|
|
92
|
+
self.main_layout.addWidget(self.submit_btn)
|
|
92
93
|
self.submit_btn.setEnabled(False)
|
|
93
94
|
|
|
94
95
|
#self.populate_left_panel()
|
|
@@ -214,7 +215,7 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
214
215
|
self.cancel_dataset = QPushButton()
|
|
215
216
|
self.cancel_dataset.setIcon(icon(MDI6.close,color="black"))
|
|
216
217
|
self.cancel_dataset.clicked.connect(self.clear_dataset)
|
|
217
|
-
self.cancel_dataset.setStyleSheet(self.
|
|
218
|
+
self.cancel_dataset.setStyleSheet(self.button_select_all)
|
|
218
219
|
self.cancel_dataset.setIconSize(QSize(20, 20))
|
|
219
220
|
self.cancel_dataset.setVisible(False)
|
|
220
221
|
train_data_layout.addWidget(self.cancel_dataset, 5)
|
|
@@ -291,7 +292,7 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
291
292
|
self.cancel_pretrained = QPushButton()
|
|
292
293
|
self.cancel_pretrained.setIcon(icon(MDI6.close,color="black"))
|
|
293
294
|
self.cancel_pretrained.clicked.connect(self.clear_pretrained)
|
|
294
|
-
self.cancel_pretrained.setStyleSheet(self.
|
|
295
|
+
self.cancel_pretrained.setStyleSheet(self.button_select_all)
|
|
295
296
|
self.cancel_pretrained.setIconSize(QSize(20, 20))
|
|
296
297
|
self.cancel_pretrained.setVisible(False)
|
|
297
298
|
pretrained_layout.addWidget(self.cancel_pretrained, 5)
|
|
@@ -319,13 +320,13 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
319
320
|
|
|
320
321
|
self.normalization_mode_btns[i].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
|
|
321
322
|
self.normalization_mode_btns[i].setIconSize(QSize(20, 20))
|
|
322
|
-
self.normalization_mode_btns[i].setStyleSheet(self.
|
|
323
|
+
self.normalization_mode_btns[i].setStyleSheet(self.button_select_all)
|
|
323
324
|
self.normalization_mode_btns[i].setToolTip("Switch to absolute normalization values.")
|
|
324
325
|
self.normalization_mode_btns[i].clicked.connect(partial(self.switch_normalization_mode, i))
|
|
325
326
|
|
|
326
327
|
self.normalization_clip_btns[i].setIcon(icon(MDI6.content_cut,color="black"))
|
|
327
328
|
self.normalization_clip_btns[i].setIconSize(QSize(20, 20))
|
|
328
|
-
self.normalization_clip_btns[i].setStyleSheet(self.
|
|
329
|
+
self.normalization_clip_btns[i].setStyleSheet(self.button_select_all)
|
|
329
330
|
self.normalization_clip_btns[i].clicked.connect(partial(self.switch_clipping_mode, i))
|
|
330
331
|
self.normalization_clip_btns[i].setToolTip('clip')
|
|
331
332
|
|
|
@@ -585,7 +586,7 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
585
586
|
|
|
586
587
|
train_signal_model(model_folder+"training_instructions.json")
|
|
587
588
|
|
|
588
|
-
self.
|
|
589
|
+
self.parent_window.refresh_signal_models()
|
|
589
590
|
|
|
590
591
|
|
|
591
592
|
def check_valid_channels(self):
|
|
@@ -609,7 +610,7 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
609
610
|
if self.normalization_mode[index]:
|
|
610
611
|
self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
|
|
611
612
|
self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
|
|
612
|
-
self.normalization_mode_btns[index].setStyleSheet(self.
|
|
613
|
+
self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
|
|
613
614
|
self.normalization_mode_btns[index].setToolTip("Switch to absolute normalization values.")
|
|
614
615
|
self.normalization_min_value_lbl[index].setText('Min %: ')
|
|
615
616
|
self.normalization_max_value_lbl[index].setText('Max %: ')
|
|
@@ -619,7 +620,7 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
619
620
|
else:
|
|
620
621
|
self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle_outline,color="black"))
|
|
621
622
|
self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
|
|
622
|
-
self.normalization_mode_btns[index].setStyleSheet(self.
|
|
623
|
+
self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
|
|
623
624
|
self.normalization_mode_btns[index].setToolTip("Switch to percentile normalization values.")
|
|
624
625
|
self.normalization_min_value_lbl[index].setText('Min: ')
|
|
625
626
|
self.normalization_min_value_le[index].setText('0')
|
|
@@ -634,10 +635,10 @@ class ConfigSignalModelTraining(QMainWindow):
|
|
|
634
635
|
if self.clip_option[index]:
|
|
635
636
|
self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="#1565c0"))
|
|
636
637
|
self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
|
|
637
|
-
self.normalization_clip_btns[index].setStyleSheet(self.
|
|
638
|
+
self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
|
|
638
639
|
|
|
639
640
|
else:
|
|
640
641
|
self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="black"))
|
|
641
642
|
self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
|
|
642
|
-
self.normalization_clip_btns[index].setStyleSheet(self.
|
|
643
|
+
self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
|
|
643
644
|
|
|
@@ -10,18 +10,19 @@ from glob import glob
|
|
|
10
10
|
import os
|
|
11
11
|
import json
|
|
12
12
|
import shutil
|
|
13
|
+
from celldetective.gui import Styles
|
|
13
14
|
|
|
14
|
-
class SegmentationModelLoader(QWidget):
|
|
15
|
+
class SegmentationModelLoader(QWidget, Styles):
|
|
15
16
|
|
|
16
17
|
"""
|
|
17
18
|
Upload a segmentation model or define a Threshold pipeline.
|
|
18
19
|
"""
|
|
19
20
|
|
|
20
|
-
def __init__(self,
|
|
21
|
+
def __init__(self, parent_window):
|
|
21
22
|
|
|
22
23
|
super().__init__()
|
|
23
|
-
self.
|
|
24
|
-
self.mode = self.
|
|
24
|
+
self.parent_window = parent_window
|
|
25
|
+
self.mode = self.parent_window.mode
|
|
25
26
|
if self.mode=="targets":
|
|
26
27
|
self.target_folder = "segmentation_targets"
|
|
27
28
|
elif self.mode=="effectors":
|
|
@@ -29,6 +30,7 @@ class SegmentationModelLoader(QWidget):
|
|
|
29
30
|
self.setWindowTitle('Upload model')
|
|
30
31
|
self.generate_content()
|
|
31
32
|
center_window(self)
|
|
33
|
+
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
32
34
|
|
|
33
35
|
def generate_content(self):
|
|
34
36
|
|
|
@@ -83,7 +85,7 @@ class SegmentationModelLoader(QWidget):
|
|
|
83
85
|
self.upload_button.clicked.connect(self.upload_model)
|
|
84
86
|
self.upload_button.setIcon(icon(MDI6.upload,color="white"))
|
|
85
87
|
self.upload_button.setIconSize(QSize(25, 25))
|
|
86
|
-
self.upload_button.setStyleSheet(self.
|
|
88
|
+
self.upload_button.setStyleSheet(self.button_style_sheet)
|
|
87
89
|
self.upload_button.setEnabled(False)
|
|
88
90
|
self.layout.addWidget(self.upload_button, 10, 0, 1, 1)
|
|
89
91
|
|
|
@@ -121,31 +123,37 @@ class SegmentationModelLoader(QWidget):
|
|
|
121
123
|
|
|
122
124
|
self.base_block = QGridLayout()
|
|
123
125
|
|
|
126
|
+
pixel_calib_layout = QHBoxLayout()
|
|
124
127
|
self.calibration_label = QLabel("pixel calibration: ")
|
|
125
|
-
self.base_block.addWidget(self.calibration_label,0,0,1,1, alignment=Qt.AlignLeft)
|
|
126
128
|
self.spatial_calib_le = QLineEdit("0,1")
|
|
127
|
-
self.qdv = QDoubleValidator(0.0, np.amax([self.
|
|
129
|
+
self.qdv = QDoubleValidator(0.0, np.amax([self.parent_window.parent_window.shape_x, self.parent_window.parent_window.shape_y]), 8, notation=QDoubleValidator.StandardNotation)
|
|
128
130
|
self.spatial_calib_le.setValidator(self.qdv)
|
|
129
|
-
|
|
131
|
+
pixel_calib_layout.addWidget(self.calibration_label, 30)
|
|
132
|
+
pixel_calib_layout.addWidget(self.spatial_calib_le, 70)
|
|
133
|
+
self.base_block.addLayout(pixel_calib_layout, 0,0,1,3)
|
|
130
134
|
|
|
131
135
|
self.channel_options = ["--","live_nuclei_channel", "dead_nuclei_channel", "effector_fluo_channel", "brightfield_channel", "adhesion_channel", "fluo_channel_1", "fluo_channel_2"]
|
|
132
|
-
exp_channels = self.
|
|
136
|
+
exp_channels = self.parent_window.parent_window.exp_channels
|
|
133
137
|
for ec in exp_channels:
|
|
134
138
|
if ec not in self.channel_options:
|
|
135
139
|
self.channel_options.append(ec)
|
|
136
140
|
self.channel_options += ['None']
|
|
137
141
|
|
|
142
|
+
channel_1_layout = QHBoxLayout()
|
|
138
143
|
self.ch_1_label = QLabel("channel 1: ")
|
|
139
|
-
self.base_block.addWidget(self.ch_1_label, 1, 0, 1, 1, alignment=Qt.AlignLeft)
|
|
140
144
|
self.combo_ch1 = QComboBox()
|
|
141
145
|
self.combo_ch1.addItems(self.channel_options)
|
|
142
|
-
|
|
146
|
+
channel_1_layout.addWidget(self.ch_1_label,30)
|
|
147
|
+
channel_1_layout.addWidget(self.combo_ch1, 70)
|
|
148
|
+
self.base_block.addLayout(channel_1_layout, 1, 0, 1, 3, alignment=Qt.AlignRight)
|
|
143
149
|
|
|
150
|
+
channel_2_layout = QHBoxLayout()
|
|
144
151
|
self.ch_2_label = QLabel("channel 2: ")
|
|
145
|
-
self.base_block.addWidget(self.ch_2_label, 2, 0, 1, 1, alignment=Qt.AlignLeft)
|
|
146
152
|
self.combo_ch2 = QComboBox()
|
|
147
153
|
self.combo_ch2.addItems(self.channel_options)
|
|
148
|
-
|
|
154
|
+
channel_2_layout.addWidget(self.ch_2_label, 30)
|
|
155
|
+
channel_2_layout.addWidget(self.combo_ch2, 70)
|
|
156
|
+
self.base_block.addLayout(channel_2_layout, 2, 0, 1, 3, alignment=Qt.AlignRight)
|
|
149
157
|
|
|
150
158
|
def generate_stardist_specific_block(self):
|
|
151
159
|
|
|
@@ -209,7 +217,7 @@ class SegmentationModelLoader(QWidget):
|
|
|
209
217
|
self.threshold_config_button.setIcon(icon(MDI6.auto_fix,color="#1565c0"))
|
|
210
218
|
self.threshold_config_button.setIconSize(QSize(20, 20))
|
|
211
219
|
self.threshold_config_button.setVisible(False)
|
|
212
|
-
self.threshold_config_button.setStyleSheet(self.
|
|
220
|
+
self.threshold_config_button.setStyleSheet(self.button_style_sheet_2)
|
|
213
221
|
self.threshold_config_button.clicked.connect(self.open_threshold_config_wizard)
|
|
214
222
|
self.layout.addWidget(self.threshold_config_button,3,0,1,2)
|
|
215
223
|
self.threshold_config_button.hide()
|
|
@@ -341,15 +349,17 @@ class SegmentationModelLoader(QWidget):
|
|
|
341
349
|
return None
|
|
342
350
|
|
|
343
351
|
self.generate_input_config()
|
|
344
|
-
self.
|
|
352
|
+
self.parent_window.init_seg_model_list()
|
|
345
353
|
self.close()
|
|
346
354
|
else:
|
|
347
355
|
if self.mode=="targets":
|
|
348
|
-
self.
|
|
356
|
+
self.parent_window.threshold_config_targets = self.filename
|
|
357
|
+
self.parent_window.seg_model_list.setCurrentText('Threshold')
|
|
349
358
|
print('Path to threshold configuration successfully set in the software')
|
|
350
359
|
self.close()
|
|
351
360
|
elif self.mode=="effectors":
|
|
352
|
-
self.
|
|
361
|
+
self.parent_window.threshold_config_effectors = self.filename
|
|
362
|
+
self.parent_window.seg_model_list.setCurrentText('Threshold')
|
|
353
363
|
print('Path to threshold configuration successfully set in the software')
|
|
354
364
|
self.close()
|
|
355
365
|
|
|
@@ -446,15 +456,9 @@ class SegmentationModelLoader(QWidget):
|
|
|
446
456
|
|
|
447
457
|
def open_threshold_config_wizard(self):
|
|
448
458
|
|
|
449
|
-
|
|
459
|
+
self.parent_window.parent_window.locate_image()
|
|
460
|
+
if self.parent_window.parent_window.current_stack is None:
|
|
461
|
+
return None
|
|
462
|
+
else:
|
|
450
463
|
self.ThreshWizard = ThresholdConfigWizard(self)
|
|
451
464
|
self.ThreshWizard.show()
|
|
452
|
-
else:
|
|
453
|
-
msgBox = QMessageBox()
|
|
454
|
-
msgBox.setIcon(QMessageBox.Warning)
|
|
455
|
-
msgBox.setText("Please select a unique position before launching the wizard...")
|
|
456
|
-
msgBox.setWindowTitle("Warning")
|
|
457
|
-
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
458
|
-
returnValue = msgBox.exec()
|
|
459
|
-
if returnValue == QMessageBox.Ok:
|
|
460
|
-
return None
|