celldetective 1.4.0__py3-none-any.whl → 1.4.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/_version.py +1 -1
- celldetective/exceptions.py +11 -0
- celldetective/filters.py +7 -1
- celldetective/gui/InitWindow.py +4 -1
- celldetective/gui/__init__.py +2 -9
- celldetective/gui/about.py +2 -2
- celldetective/gui/base_annotator.py +786 -0
- celldetective/gui/classifier_widget.py +18 -13
- celldetective/gui/configure_new_exp.py +51 -30
- celldetective/gui/control_panel.py +10 -7
- celldetective/gui/{signal_annotator.py → event_annotator.py} +473 -1437
- celldetective/gui/generic_signal_plot.py +2 -1
- celldetective/gui/gui_utils.py +5 -2
- celldetective/gui/help/neighborhood.json +2 -2
- celldetective/gui/layouts.py +21 -11
- celldetective/gui/{signal_annotator2.py → pair_event_annotator.py} +3 -1
- celldetective/gui/process_block.py +129 -91
- celldetective/gui/processes/downloader.py +37 -34
- celldetective/gui/processes/measure_cells.py +14 -8
- celldetective/gui/processes/segment_cells.py +21 -6
- celldetective/gui/processes/track_cells.py +12 -13
- celldetective/gui/settings/__init__.py +7 -0
- celldetective/gui/settings/_settings_base.py +70 -0
- celldetective/gui/{retrain_signal_model_options.py → settings/_settings_event_model_training.py} +35 -91
- celldetective/gui/{measurement_options.py → settings/_settings_measurements.py} +28 -81
- celldetective/gui/{neighborhood_options.py → settings/_settings_neighborhood.py} +1 -1
- celldetective/gui/settings/_settings_segmentation.py +49 -0
- celldetective/gui/{retrain_segmentation_model_options.py → settings/_settings_segmentation_model_training.py} +33 -79
- celldetective/gui/{signal_annotator_options.py → settings/_settings_signal_annotator.py} +73 -95
- celldetective/gui/{btrack_options.py → settings/_settings_tracking.py} +64 -87
- celldetective/gui/styles.py +2 -1
- celldetective/gui/survival_ui.py +1 -1
- celldetective/gui/tableUI.py +25 -0
- celldetective/gui/table_ops/__init__.py +0 -0
- celldetective/gui/table_ops/merge_groups.py +118 -0
- celldetective/gui/viewers.py +3 -5
- celldetective/gui/workers.py +0 -2
- celldetective/io.py +98 -55
- celldetective/links/zenodo.json +145 -144
- celldetective/measure.py +31 -26
- celldetective/preprocessing.py +34 -21
- celldetective/regionprops/_regionprops.py +16 -5
- celldetective/scripts/measure_cells.py +5 -5
- celldetective/scripts/measure_relative.py +16 -11
- celldetective/scripts/segment_cells.py +4 -4
- celldetective/scripts/segment_cells_thresholds.py +3 -3
- celldetective/scripts/track_cells.py +7 -7
- celldetective/scripts/train_segmentation_model.py +10 -1
- celldetective/tracking.py +10 -4
- celldetective/utils.py +59 -58
- {celldetective-1.4.0.dist-info → celldetective-1.4.1.dist-info}/METADATA +1 -1
- celldetective-1.4.1.dist-info/RECORD +123 -0
- tests/gui/__init__.py +0 -0
- tests/gui/test_new_project.py +228 -0
- tests/{test_qt.py → gui/test_project.py} +22 -26
- tests/test_preprocessing.py +2 -2
- celldetective/models/segmentation_effectors/ricm_bf_all_last/config_input.json +0 -79
- celldetective/models/segmentation_effectors/ricm_bf_all_last/ricm_bf_all_last +0 -0
- celldetective/models/segmentation_effectors/ricm_bf_all_last/training_instructions.json +0 -37
- celldetective/models/segmentation_effectors/test-transfer/config_input.json +0 -39
- celldetective/models/segmentation_effectors/test-transfer/test-transfer +0 -0
- celldetective/models/signal_detection/NucCond/classification_loss.png +0 -0
- celldetective/models/signal_detection/NucCond/classifier.h5 +0 -0
- celldetective/models/signal_detection/NucCond/config_input.json +0 -1
- celldetective/models/signal_detection/NucCond/log_classifier.csv +0 -126
- celldetective/models/signal_detection/NucCond/log_regressor.csv +0 -282
- celldetective/models/signal_detection/NucCond/regression_loss.png +0 -0
- celldetective/models/signal_detection/NucCond/regressor.h5 +0 -0
- celldetective/models/signal_detection/NucCond/scores.npy +0 -0
- celldetective/models/signal_detection/NucCond/test_confusion_matrix.png +0 -0
- celldetective/models/signal_detection/NucCond/test_regression.png +0 -0
- celldetective/models/signal_detection/NucCond/validation_confusion_matrix.png +0 -0
- celldetective/models/signal_detection/NucCond/validation_regression.png +0 -0
- celldetective-1.4.0.dist-info/RECORD +0 -131
- {celldetective-1.4.0.dist-info → celldetective-1.4.1.dist-info}/WHEEL +0 -0
- {celldetective-1.4.0.dist-info → celldetective-1.4.1.dist-info}/entry_points.txt +0 -0
- {celldetective-1.4.0.dist-info → celldetective-1.4.1.dist-info}/licenses/LICENSE +0 -0
- {celldetective-1.4.0.dist-info → celldetective-1.4.1.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from subprocess import Popen
|
|
2
2
|
|
|
3
|
-
from PyQt5.QtWidgets import
|
|
3
|
+
from PyQt5.QtWidgets import QMessageBox, QComboBox, QFrame, QCheckBox, \
|
|
4
4
|
QGridLayout, QLineEdit, QVBoxLayout, QLabel, QHBoxLayout, QPushButton
|
|
5
5
|
from PyQt5.QtCore import Qt, QSize
|
|
6
|
-
from PyQt5.QtGui import QDoubleValidator, QIntValidator
|
|
7
6
|
|
|
8
|
-
from celldetective.gui.gui_utils import
|
|
7
|
+
from celldetective.gui.gui_utils import FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, \
|
|
9
8
|
GeometryChoice, OperationChoice
|
|
10
9
|
from superqt import QLabeledDoubleSlider
|
|
11
10
|
from superqt.fonticon import icon
|
|
@@ -27,10 +26,10 @@ from pathlib import Path
|
|
|
27
26
|
from celldetective.gui.viewers import CellEdgeVisualizer, SpotDetectionVisualizer
|
|
28
27
|
from celldetective.gui.layouts import ProtocolDesignerLayout, BackgroundFitCorrectionLayout, LocalCorrectionLayout
|
|
29
28
|
from celldetective.gui.gui_utils import PreprocessingLayout2
|
|
30
|
-
from celldetective.gui import
|
|
29
|
+
from celldetective.gui.settings._settings_base import CelldetectiveSettingsPanel
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
class
|
|
32
|
+
class SettingsMeasurements(CelldetectiveSettingsPanel):
|
|
34
33
|
"""
|
|
35
34
|
UI to set measurement instructions.
|
|
36
35
|
|
|
@@ -38,49 +37,33 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
38
37
|
|
|
39
38
|
def __init__(self, parent_window=None):
|
|
40
39
|
|
|
41
|
-
super().__init__()
|
|
42
|
-
|
|
43
40
|
self.parent_window = parent_window
|
|
44
|
-
self.setWindowTitle("Configure measurements")
|
|
45
41
|
self.mode = self.parent_window.mode
|
|
46
42
|
self.exp_dir = self.parent_window.exp_dir
|
|
47
43
|
self.background_correction = []
|
|
48
44
|
self.config_name = f"btrack_config_{self.mode}.json"
|
|
49
45
|
self.measure_instructions_path = self.parent_window.exp_dir + f"configs/measurement_instructions_{self.mode}.json"
|
|
50
|
-
self.soft_path = get_software_location()
|
|
51
46
|
self.clear_previous = False
|
|
52
|
-
|
|
53
|
-
exp_config = self.exp_dir + "config.ini"
|
|
54
47
|
self.config_path = self.exp_dir + self.config_name
|
|
55
48
|
self.channel_names, self.channels = extract_experiment_channels(self.exp_dir)
|
|
56
49
|
self.channel_names = np.array(self.channel_names)
|
|
57
50
|
self.channels = np.array(self.channels)
|
|
51
|
+
|
|
52
|
+
super().__init__("Configure measurements")
|
|
58
53
|
|
|
59
|
-
self.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
self.
|
|
63
|
-
self.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
self.setMinimumHeight(int(0.3 * self.screen_height))
|
|
67
|
-
self.setMaximumHeight(int(0.8 * self.screen_height))
|
|
68
|
-
self.populate_widget()
|
|
69
|
-
self.load_previous_measurement_instructions()
|
|
70
|
-
|
|
71
|
-
def populate_widget(self):
|
|
54
|
+
self._add_to_layout()
|
|
55
|
+
self._load_previous_instructions()
|
|
56
|
+
|
|
57
|
+
self._adjustSize()
|
|
58
|
+
self.resize(int(self.width()), int(self._screen_height * 0.8))
|
|
59
|
+
|
|
60
|
+
def _create_widgets(self):
|
|
72
61
|
|
|
73
62
|
"""
|
|
74
63
|
Create the multibox design.
|
|
75
64
|
|
|
76
65
|
"""
|
|
77
|
-
|
|
78
|
-
# Create button widget and layout
|
|
79
|
-
self.scroll_area = QScrollArea(self)
|
|
80
|
-
self.button_widget = CelldetectiveWidget()
|
|
81
|
-
main_layout = QVBoxLayout()
|
|
82
|
-
self.button_widget.setLayout(main_layout)
|
|
83
|
-
main_layout.setContentsMargins(30, 30, 30, 30)
|
|
66
|
+
super()._create_widgets()
|
|
84
67
|
|
|
85
68
|
self.normalisation_frame = QFrame()
|
|
86
69
|
self.normalisation_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
@@ -98,48 +81,31 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
98
81
|
self.normalisation_frame.setLayout(self.protocol_layout)
|
|
99
82
|
|
|
100
83
|
#self.populate_normalisation_tabs()
|
|
101
|
-
main_layout.addWidget(self.normalisation_frame)
|
|
102
84
|
|
|
103
85
|
# first frame for FEATURES
|
|
104
86
|
self.features_frame = QFrame()
|
|
105
87
|
self.features_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
106
88
|
self.populate_features_frame()
|
|
107
|
-
main_layout.addWidget(self.features_frame)
|
|
108
89
|
|
|
109
90
|
# second frame for ISOTROPIC MEASUREMENTS
|
|
110
91
|
self.iso_frame = QFrame()
|
|
111
92
|
self.iso_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
112
93
|
self.populate_iso_frame()
|
|
113
|
-
main_layout.addWidget(self.iso_frame)
|
|
114
94
|
|
|
115
95
|
self.spot_detection_frame = QFrame()
|
|
116
96
|
self.spot_detection_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
117
97
|
self.populate_spot_detection()
|
|
118
|
-
main_layout.addWidget(self.spot_detection_frame)
|
|
119
98
|
|
|
120
99
|
self.clear_previous_btn = QCheckBox('clear previous measurements')
|
|
121
|
-
main_layout.addWidget(self.clear_previous_btn)
|
|
122
|
-
|
|
123
|
-
self.submit_btn = QPushButton('Save')
|
|
124
|
-
self.submit_btn.setStyleSheet(self.button_style_sheet)
|
|
125
|
-
self.submit_btn.clicked.connect(self.write_instructions)
|
|
126
|
-
main_layout.addWidget(self.submit_btn)
|
|
127
|
-
|
|
128
|
-
# self.populate_left_panel()
|
|
129
|
-
# grid.addLayout(self.left_side, 0, 0, 1, 1)
|
|
130
|
-
self.button_widget.adjustSize()
|
|
131
|
-
|
|
132
|
-
self.scroll_area.setAlignment(Qt.AlignCenter)
|
|
133
|
-
self.scroll_area.setWidget(self.button_widget)
|
|
134
|
-
self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
135
|
-
self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
136
|
-
self.scroll_area.setWidgetResizable(True)
|
|
137
|
-
self.setCentralWidget(self.scroll_area)
|
|
138
|
-
self.show()
|
|
139
|
-
|
|
140
|
-
QApplication.processEvents()
|
|
141
|
-
self.adjustScrollArea()
|
|
142
100
|
|
|
101
|
+
def _add_to_layout(self):
|
|
102
|
+
self._layout.addWidget(self.normalisation_frame)
|
|
103
|
+
self._layout.addWidget(self.features_frame)
|
|
104
|
+
self._layout.addWidget(self.iso_frame)
|
|
105
|
+
self._layout.addWidget(self.spot_detection_frame)
|
|
106
|
+
self._layout.addWidget(self.clear_previous_btn)
|
|
107
|
+
self._layout.addWidget(self.submit_btn)
|
|
108
|
+
|
|
143
109
|
def populate_iso_frame(self):
|
|
144
110
|
|
|
145
111
|
"""
|
|
@@ -431,7 +397,7 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
431
397
|
|
|
432
398
|
def go_to_extraprops(self):
|
|
433
399
|
|
|
434
|
-
path = os.sep.join([self.
|
|
400
|
+
path = os.sep.join([self._software_path,'celldetective',os.sep,'extra_properties.py'])
|
|
435
401
|
try:
|
|
436
402
|
Popen(f'explorer {os.path.realpath(path)}')
|
|
437
403
|
except:
|
|
@@ -487,7 +453,7 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
487
453
|
while self.scroll_area.verticalScrollBar().isVisible() and self.height() < self.maximumHeight():
|
|
488
454
|
self.resize(self.width(), self.height() + step)
|
|
489
455
|
|
|
490
|
-
def
|
|
456
|
+
def _write_instructions(self):
|
|
491
457
|
|
|
492
458
|
"""
|
|
493
459
|
Write the selected options in a json file for later reading by the software.
|
|
@@ -566,7 +532,7 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
566
532
|
else:
|
|
567
533
|
self.haralick_options = None
|
|
568
534
|
|
|
569
|
-
def
|
|
535
|
+
def _load_previous_instructions(self):
|
|
570
536
|
|
|
571
537
|
"""
|
|
572
538
|
Read the measurmeent options from a previously written json file and format properly for the UI.
|
|
@@ -685,18 +651,6 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
685
651
|
else:
|
|
686
652
|
self.operations_list.list_widget.clear()
|
|
687
653
|
|
|
688
|
-
# if 'radial_intensity' in measurement_instructions:
|
|
689
|
-
# radial_intensity = measurement_instructions['radial_intensity']
|
|
690
|
-
# if radial_intensity is not None:
|
|
691
|
-
# self.radial_intensity_btn.setChecked(True)
|
|
692
|
-
# self.step_size.setText(str(radial_intensity['radial_step']))
|
|
693
|
-
# self.step_size.setEnabled(True)
|
|
694
|
-
# self.step_lbl.setEnabled(True)
|
|
695
|
-
# for checkbox in self.channel_chechkboxes:
|
|
696
|
-
# checkbox.setEnabled(True)
|
|
697
|
-
# if checkbox.text() in radial_intensity['radial_channels']:
|
|
698
|
-
# checkbox.setChecked(True)
|
|
699
|
-
|
|
700
654
|
if 'clear_previous' in measurement_instructions:
|
|
701
655
|
self.clear_previous = measurement_instructions['clear_previous']
|
|
702
656
|
self.clear_previous_btn.setChecked(self.clear_previous)
|
|
@@ -718,6 +672,7 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
718
672
|
returnValue = msgBox.exec()
|
|
719
673
|
if returnValue == QMessageBox.Ok:
|
|
720
674
|
self.current_stack = None
|
|
675
|
+
self.test_frame = None
|
|
721
676
|
return None
|
|
722
677
|
else:
|
|
723
678
|
self.current_stack = movies[0]
|
|
@@ -946,7 +901,7 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
946
901
|
diam_hbox = QHBoxLayout()
|
|
947
902
|
self.diameter_lbl = QLabel('Spot diameter: ')
|
|
948
903
|
self.diameter_value = QLineEdit()
|
|
949
|
-
self.diameter_value.setValidator(self.
|
|
904
|
+
self.diameter_value.setValidator(self._floatValidator)
|
|
950
905
|
self.diameter_value.setText('7')
|
|
951
906
|
self.diameter_value.textChanged.connect(self.enable_spot_preview)
|
|
952
907
|
|
|
@@ -957,7 +912,7 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
957
912
|
thresh_hbox = QHBoxLayout()
|
|
958
913
|
self.threshold_lbl = QLabel('Spot threshold: ')
|
|
959
914
|
self.threshold_value = QLineEdit()
|
|
960
|
-
self.threshold_value.setValidator(self.
|
|
915
|
+
self.threshold_value.setValidator(self._floatValidator)
|
|
961
916
|
self.threshold_value.setText('0')
|
|
962
917
|
self.threshold_value.textChanged.connect(self.enable_spot_preview)
|
|
963
918
|
|
|
@@ -965,14 +920,6 @@ class ConfigMeasurements(CelldetectiveMainWindow):
|
|
|
965
920
|
thresh_hbox.addWidget(self.threshold_value, 70)
|
|
966
921
|
layout.addLayout(thresh_hbox)
|
|
967
922
|
|
|
968
|
-
# #invert_layout = QHBoxLayout()
|
|
969
|
-
# self.invert_check = QCheckBox('invert')
|
|
970
|
-
# self.invert_value_le = QLineEdit('65535')
|
|
971
|
-
# self.invert_value_le.setValidator(self.onlyFloat)
|
|
972
|
-
# layout.addWidget(self.invert_check, 6, 0)
|
|
973
|
-
# layout.addWidget(self.invert_value_le, 6, 1)
|
|
974
|
-
# #layout.addLayout(invert_layout, 5, 1, 1, 1)
|
|
975
|
-
|
|
976
923
|
self.spot_detection_widgets = [self.spot_channel,
|
|
977
924
|
self.spot_channel_lbl,
|
|
978
925
|
self.diameter_value,
|
|
@@ -12,7 +12,7 @@ from celldetective.gui.viewers import CellSizeViewer, CellEdgeVisualizer
|
|
|
12
12
|
from celldetective.gui import CelldetectiveWidget
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
class
|
|
15
|
+
class SettingsNeighborhood(CelldetectiveWidget):
|
|
16
16
|
|
|
17
17
|
"""
|
|
18
18
|
Widget to configure neighborhood measurements.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from PyQt5.QtWidgets import QCheckBox
|
|
2
|
+
from PyQt5.QtCore import QSize
|
|
3
|
+
from superqt.fonticon import icon
|
|
4
|
+
from fonticon_mdi6 import MDI6
|
|
5
|
+
from celldetective.gui.settings._settings_base import CelldetectiveSettingsPanel
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
class SettingsSegmentation(CelldetectiveSettingsPanel):
|
|
10
|
+
|
|
11
|
+
def __init__(self, parent_window=None):
|
|
12
|
+
|
|
13
|
+
super().__init__(title="Configure segmentation")
|
|
14
|
+
self.parent_window = parent_window
|
|
15
|
+
self.mode = self.parent_window.mode
|
|
16
|
+
self.exp_dir = self.parent_window.exp_dir
|
|
17
|
+
self._instructions_path = self.parent_window.exp_dir + f"configs/segmentation_instructions_{self.mode}.json"
|
|
18
|
+
self._add_to_layout()
|
|
19
|
+
self._load_previous_instructions()
|
|
20
|
+
|
|
21
|
+
def _create_widgets(self):
|
|
22
|
+
super()._create_widgets()
|
|
23
|
+
|
|
24
|
+
self.flip_segmentation_checkbox: QCheckBox = QCheckBox("Segment frames in reverse order")
|
|
25
|
+
self.flip_segmentation_checkbox.setIcon(icon(MDI6.camera_flip_outline,color="black"))
|
|
26
|
+
self.flip_segmentation_checkbox.setIconSize(QSize(20, 20))
|
|
27
|
+
self.flip_segmentation_checkbox.setStyleSheet(self.button_select_all)
|
|
28
|
+
self.flip_segmentation_checkbox.setToolTip("Flip the order of the frames for segmentation.")
|
|
29
|
+
|
|
30
|
+
def _add_to_layout(self):
|
|
31
|
+
self._layout.addWidget(self.flip_segmentation_checkbox)
|
|
32
|
+
self._layout.addWidget(self.submit_btn)
|
|
33
|
+
#self._widget.adjustSize()
|
|
34
|
+
|
|
35
|
+
def _load_previous_instructions(self):
|
|
36
|
+
if os.path.exists(self._instructions_path):
|
|
37
|
+
with open(self._instructions_path, "r") as f:
|
|
38
|
+
instructions = json.load(f)
|
|
39
|
+
if isinstance(instructions.get("flip"),bool):
|
|
40
|
+
self.flip_segmentation_checkbox.setChecked(instructions.get("flip"))
|
|
41
|
+
|
|
42
|
+
def _write_instructions(self):
|
|
43
|
+
instructions = {"flip": self.flip_segmentation_checkbox.isChecked()}
|
|
44
|
+
print('Segmentation instructions: ', instructions)
|
|
45
|
+
file_name = self._instructions_path
|
|
46
|
+
with open(file_name, 'w') as f:
|
|
47
|
+
json.dump(instructions, f, indent=4)
|
|
48
|
+
print('Done.')
|
|
49
|
+
self.close()
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
from PyQt5.QtWidgets import
|
|
1
|
+
from PyQt5.QtWidgets import QRadioButton, QComboBox, QFrame, QFileDialog, QGridLayout, QLineEdit, QVBoxLayout, QLabel, QHBoxLayout, QPushButton
|
|
2
2
|
from PyQt5.QtCore import Qt, QSize
|
|
3
|
-
from
|
|
4
|
-
from celldetective.gui.gui_utils import center_window, generic_message
|
|
3
|
+
from celldetective.gui.gui_utils import generic_message
|
|
5
4
|
from celldetective.gui.layouts import ChannelNormGenerator
|
|
6
5
|
|
|
7
6
|
from superqt import QLabeledDoubleSlider,QLabeledSlider
|
|
8
7
|
from superqt.fonticon import icon
|
|
9
8
|
from fonticon_mdi6 import MDI6
|
|
10
|
-
from celldetective.utils import get_software_location
|
|
11
9
|
from celldetective.io import get_segmentation_datasets_list, locate_segmentation_dataset, get_segmentation_models_list
|
|
12
10
|
from celldetective.segmentation import train_segmentation_model
|
|
13
11
|
from celldetective.gui.layouts import CellposeParamsWidget
|
|
@@ -16,10 +14,9 @@ import json
|
|
|
16
14
|
import os
|
|
17
15
|
from glob import glob
|
|
18
16
|
from datetime import datetime
|
|
19
|
-
from celldetective.gui import
|
|
17
|
+
from celldetective.gui.settings._settings_base import CelldetectiveSettingsPanel
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
|
|
19
|
+
class SettingsSegmentationModelTraining(CelldetectiveSettingsPanel):
|
|
23
20
|
|
|
24
21
|
"""
|
|
25
22
|
UI to set segmentation model training instructions.
|
|
@@ -28,85 +25,56 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
|
|
|
28
25
|
|
|
29
26
|
def __init__(self, parent_window=None):
|
|
30
27
|
|
|
31
|
-
super().__init__()
|
|
32
28
|
self.parent_window = parent_window
|
|
33
29
|
self.use_gpu = self.parent_window.use_gpu
|
|
34
|
-
self.setWindowTitle("Train segmentation model")
|
|
35
30
|
self.mode = self.parent_window.mode
|
|
36
31
|
self.exp_dir = self.parent_window.exp_dir
|
|
37
|
-
self.
|
|
38
|
-
self.pretrained_model = None
|
|
32
|
+
self.pretrained_model = None
|
|
39
33
|
self.dataset_folder = None
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
self.onlyFloat = QDoubleValidator()
|
|
43
|
-
self.onlyInt = QIntValidator()
|
|
44
|
-
|
|
45
|
-
self.screen_height = self.parent_window.parent_window.parent_window.screen_height
|
|
46
|
-
center_window(self)
|
|
47
|
-
|
|
48
|
-
self.setMinimumWidth(500)
|
|
49
|
-
self.setMinimumHeight(int(0.3*self.screen_height))
|
|
50
|
-
self.setMaximumHeight(int(0.8*self.screen_height))
|
|
51
|
-
self.populate_widget()
|
|
52
|
-
#self.load_previous_measurement_instructions()
|
|
34
|
+
super().__init__(title="Train segmentation model")
|
|
53
35
|
|
|
54
|
-
|
|
36
|
+
self.software_models_dir = os.sep.join([self._software_path, 'celldetective', 'models', f'segmentation_{self.mode}'])
|
|
37
|
+
self._add_to_layout()
|
|
38
|
+
self._load_previous_instructions()
|
|
39
|
+
|
|
40
|
+
self._adjustSize()
|
|
41
|
+
self.resize(int(self.width()), int(self._screen_height * 0.8))
|
|
42
|
+
|
|
43
|
+
def _add_to_layout(self):
|
|
44
|
+
|
|
45
|
+
self._layout.addWidget(self.model_frame)
|
|
46
|
+
self._layout.addWidget(self.data_frame)
|
|
47
|
+
self._layout.addWidget(self.hyper_frame)
|
|
48
|
+
self._layout.addWidget(self.submit_warning)
|
|
49
|
+
self._layout.addWidget(self.submit_btn)
|
|
50
|
+
|
|
51
|
+
def _create_widgets(self):
|
|
55
52
|
|
|
56
53
|
"""
|
|
57
54
|
Create the multibox design.
|
|
58
55
|
|
|
59
56
|
"""
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
self.scroll_area = QScrollArea(self)
|
|
63
|
-
self.button_widget = CelldetectiveWidget()
|
|
64
|
-
self.main_layout = QVBoxLayout()
|
|
65
|
-
self.button_widget.setLayout(self.main_layout)
|
|
66
|
-
self.main_layout.setContentsMargins(30,30,30,30)
|
|
67
|
-
|
|
68
|
-
# first frame for FEATURES
|
|
58
|
+
super()._create_widgets()
|
|
69
59
|
self.model_frame = QFrame()
|
|
70
60
|
self.model_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
71
61
|
self.populate_model_frame()
|
|
72
|
-
self.main_layout.addWidget(self.model_frame)
|
|
73
62
|
|
|
74
63
|
self.data_frame = QFrame()
|
|
75
64
|
self.data_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
76
65
|
self.populate_data_frame()
|
|
77
|
-
self.main_layout.addWidget(self.data_frame)
|
|
78
66
|
|
|
79
67
|
self.hyper_frame = QFrame()
|
|
80
68
|
self.hyper_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
81
69
|
self.populate_hyper_frame()
|
|
82
|
-
self.main_layout.addWidget(self.hyper_frame)
|
|
83
70
|
|
|
84
|
-
self.submit_btn = QPushButton('Train')
|
|
85
|
-
self.submit_btn.setStyleSheet(self.button_style_sheet)
|
|
86
|
-
self.submit_btn.clicked.connect(self.prep_model)
|
|
87
|
-
self.main_layout.addWidget(self.submit_btn)
|
|
88
71
|
self.submit_btn.setEnabled(False)
|
|
89
72
|
self.submit_warning = QLabel('')
|
|
90
|
-
self.
|
|
73
|
+
self.submit_btn.setText("Train")
|
|
91
74
|
|
|
92
75
|
self.spatial_calib_le.textChanged.connect(self.activate_train_btn)
|
|
93
76
|
self.modelname_le.setText(f"Untitled_model_{datetime.today().strftime('%Y-%m-%d')}")
|
|
94
77
|
|
|
95
|
-
#self.populate_left_panel()
|
|
96
|
-
#grid.addLayout(self.left_side, 0, 0, 1, 1)
|
|
97
|
-
self.button_widget.adjustSize()
|
|
98
|
-
|
|
99
|
-
self.scroll_area.setAlignment(Qt.AlignCenter)
|
|
100
|
-
self.scroll_area.setWidget(self.button_widget)
|
|
101
|
-
self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
102
|
-
self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
103
|
-
self.scroll_area.setWidgetResizable(True)
|
|
104
|
-
self.setCentralWidget(self.scroll_area)
|
|
105
|
-
self.show()
|
|
106
|
-
|
|
107
|
-
QApplication.processEvents()
|
|
108
|
-
self.adjustScrollArea()
|
|
109
|
-
|
|
110
78
|
def populate_hyper_frame(self):
|
|
111
79
|
|
|
112
80
|
"""
|
|
@@ -135,14 +103,14 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
|
|
|
135
103
|
lr_layout = QHBoxLayout()
|
|
136
104
|
lr_layout.addWidget(QLabel('learning rate: '),30)
|
|
137
105
|
self.lr_le = QLineEdit('0,0003')
|
|
138
|
-
self.lr_le.setValidator(self.
|
|
106
|
+
self.lr_le.setValidator(self._floatValidator)
|
|
139
107
|
lr_layout.addWidget(self.lr_le, 70)
|
|
140
108
|
layout.addLayout(lr_layout)
|
|
141
109
|
|
|
142
110
|
bs_layout = QHBoxLayout()
|
|
143
111
|
bs_layout.addWidget(QLabel('batch size: '),30)
|
|
144
112
|
self.bs_le = QLineEdit('8')
|
|
145
|
-
self.bs_le.setValidator(self.
|
|
113
|
+
self.bs_le.setValidator(self._intValidator)
|
|
146
114
|
bs_layout.addWidget(self.bs_le, 70)
|
|
147
115
|
layout.addLayout(bs_layout)
|
|
148
116
|
|
|
@@ -318,7 +286,7 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
|
|
|
318
286
|
parent_pxtoum = f"{self.parent_window.parent_window.PxToUm}"
|
|
319
287
|
self.spatial_calib_le = QLineEdit(parent_pxtoum.replace('.',','))
|
|
320
288
|
self.spatial_calib_le.setPlaceholderText('e.g. 0.1 µm per pixel')
|
|
321
|
-
self.spatial_calib_le.setValidator(self.
|
|
289
|
+
self.spatial_calib_le.setValidator(self._floatValidator)
|
|
322
290
|
spatial_calib_layout.addWidget(self.spatial_calib_le, 70)
|
|
323
291
|
layout.addLayout(spatial_calib_layout)
|
|
324
292
|
|
|
@@ -349,17 +317,11 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
|
|
|
349
317
|
|
|
350
318
|
def showDialog_pretrained(self):
|
|
351
319
|
|
|
352
|
-
# try:
|
|
353
|
-
# self.cancel_pretrained.click()
|
|
354
|
-
# except Exception as e:
|
|
355
|
-
# print(e)
|
|
356
|
-
# pass
|
|
357
|
-
|
|
358
320
|
self.clear_pretrained()
|
|
359
321
|
self.pretrained_model = None
|
|
360
322
|
self.pretrained_model = QFileDialog.getExistingDirectory(
|
|
361
323
|
self, "Open Directory",
|
|
362
|
-
os.sep.join([self.
|
|
324
|
+
os.sep.join([self._software_path, 'celldetective', 'models', f'segmentation_generic','']),
|
|
363
325
|
QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks,
|
|
364
326
|
)
|
|
365
327
|
|
|
@@ -531,18 +493,7 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
|
|
|
531
493
|
|
|
532
494
|
self.spatial_calib_le.setText(str(spatial_calib).replace('.',','))
|
|
533
495
|
|
|
534
|
-
def
|
|
535
|
-
|
|
536
|
-
"""
|
|
537
|
-
Auto-adjust scroll area to fill space
|
|
538
|
-
(from https://stackoverflow.com/questions/66417576/make-qscrollarea-use-all-available-space-of-qmainwindow-height-axis)
|
|
539
|
-
"""
|
|
540
|
-
|
|
541
|
-
step = 5
|
|
542
|
-
while self.scroll_area.verticalScrollBar().isVisible() and self.height() < self.maximumHeight():
|
|
543
|
-
self.resize(self.width(), self.height() + step)
|
|
544
|
-
|
|
545
|
-
def prep_model(self):
|
|
496
|
+
def _write_instructions(self):
|
|
546
497
|
|
|
547
498
|
model_name = self.modelname_le.text()
|
|
548
499
|
pretrained_model = self.pretrained_model
|
|
@@ -623,4 +574,7 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
|
|
|
623
574
|
|
|
624
575
|
self.parent_window.init_seg_model_list()
|
|
625
576
|
idx = self.parent_window.seg_model_list.findText(model_name)
|
|
626
|
-
self.parent_window.seg_model_list.setCurrentIndex(idx)
|
|
577
|
+
self.parent_window.seg_model_list.setCurrentIndex(idx)
|
|
578
|
+
|
|
579
|
+
def _load_previous_instructions(self):
|
|
580
|
+
pass
|