cellects 0.1.2__py3-none-any.whl → 0.2.6__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.
- cellects/__main__.py +65 -25
- cellects/config/all_vars_dict.py +18 -17
- cellects/core/cellects_threads.py +1034 -396
- cellects/core/motion_analysis.py +1664 -2010
- cellects/core/one_image_analysis.py +1082 -1061
- cellects/core/program_organizer.py +1687 -1316
- cellects/core/script_based_run.py +80 -76
- cellects/gui/advanced_parameters.py +390 -330
- cellects/gui/cellects.py +102 -91
- cellects/gui/custom_widgets.py +16 -33
- cellects/gui/first_window.py +226 -104
- cellects/gui/if_several_folders_window.py +117 -68
- cellects/gui/image_analysis_window.py +866 -454
- cellects/gui/required_output.py +104 -57
- cellects/gui/ui_strings.py +840 -0
- cellects/gui/video_analysis_window.py +333 -155
- cellects/image_analysis/cell_leaving_detection.py +64 -4
- cellects/image_analysis/image_segmentation.py +451 -22
- cellects/image_analysis/morphological_operations.py +2166 -1635
- cellects/image_analysis/network_functions.py +616 -253
- cellects/image_analysis/one_image_analysis_threads.py +94 -153
- cellects/image_analysis/oscillations_functions.py +131 -0
- cellects/image_analysis/progressively_add_distant_shapes.py +2 -3
- cellects/image_analysis/shape_descriptors.py +517 -466
- cellects/utils/formulas.py +169 -6
- cellects/utils/load_display_save.py +362 -109
- cellects/utils/utilitarian.py +86 -9
- cellects-0.2.6.dist-info/LICENSE +675 -0
- cellects-0.2.6.dist-info/METADATA +829 -0
- cellects-0.2.6.dist-info/RECORD +44 -0
- cellects/core/one_video_per_blob.py +0 -540
- cellects/image_analysis/cluster_flux_study.py +0 -102
- cellects-0.1.2.dist-info/LICENSE.odt +0 -0
- cellects-0.1.2.dist-info/METADATA +0 -132
- cellects-0.1.2.dist-info/RECORD +0 -44
- {cellects-0.1.2.dist-info → cellects-0.2.6.dist-info}/WHEEL +0 -0
- {cellects-0.1.2.dist-info → cellects-0.2.6.dist-info}/entry_points.txt +0 -0
- {cellects-0.1.2.dist-info → cellects-0.2.6.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
|
|
2
|
+
"""GUI module implementing the Advanced Parameters configuration window for Cellects.
|
|
3
|
+
|
|
4
|
+
This module provides an interactive dialog allowing users to configure advanced image
|
|
5
|
+
analysis and processing settings. The UI organizes parameter controls into categorized boxes:
|
|
6
|
+
general parameters, cell detection rules, spatiotemporal scaling, computer resources,
|
|
7
|
+
video saving options, and color space conversion (CSC) settings. It maintains user preferences
|
|
8
|
+
in both RAM and persistent storage via "Ok" button click.
|
|
9
|
+
|
|
10
|
+
Main Components
|
|
11
|
+
AdvancedParameters : QWidget subclass for advanced parameter configuration window
|
|
12
|
+
|
|
13
|
+
Notes
|
|
14
|
+
Uses QThread for background operations to maintain UI responsiveness during parameter saving.
|
|
4
15
|
"""
|
|
5
16
|
|
|
6
17
|
|
|
@@ -15,6 +26,7 @@ from cellects.config.all_vars_dict import DefaultDicts
|
|
|
15
26
|
from cellects.core.cellects_paths import CELLECTS_DIR, CONFIG_DIR
|
|
16
27
|
from cellects.gui.custom_widgets import (
|
|
17
28
|
WindowType, PButton, Spinbox, Combobox, Checkbox, FixedText)
|
|
29
|
+
from cellects.gui.ui_strings import AP, IAW
|
|
18
30
|
|
|
19
31
|
|
|
20
32
|
class AdvancedParameters(WindowType):
|
|
@@ -25,9 +37,32 @@ class AdvancedParameters(WindowType):
|
|
|
25
37
|
Clicking "Ok" save the directory in RAM and in ROM.
|
|
26
38
|
"""
|
|
27
39
|
def __init__(self, parent, night_mode):
|
|
40
|
+
"""
|
|
41
|
+
Initialize the AdvancedParameters window with a parent widget and night mode setting.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
parent : QWidget
|
|
46
|
+
The parent widget to which this window will be attached.
|
|
47
|
+
night_mode : bool
|
|
48
|
+
A boolean indicating whether the night mode should be enabled.
|
|
49
|
+
|
|
50
|
+
Examples
|
|
51
|
+
--------
|
|
52
|
+
>>> from PySide6 import QtWidgets
|
|
53
|
+
>>> from cellects.gui.cellects import CellectsMainWidget
|
|
54
|
+
>>> from cellects.gui.advanced_parameters import AdvancedParameters
|
|
55
|
+
>>> import sys
|
|
56
|
+
>>> app = QtWidgets.QApplication([])
|
|
57
|
+
>>> parent = CellectsMainWidget()
|
|
58
|
+
>>> session = AdvancedParameters(parent, False)
|
|
59
|
+
>>> session.true_init()
|
|
60
|
+
>>> parent.insertWidget(0, session)
|
|
61
|
+
>>> parent.show()
|
|
62
|
+
>>> sys.exit(app.exec())
|
|
63
|
+
"""
|
|
28
64
|
super().__init__(parent, night_mode)
|
|
29
65
|
|
|
30
|
-
logging.info("Initialize AdvancedParameters window")
|
|
31
66
|
self.setParent(parent)
|
|
32
67
|
try:
|
|
33
68
|
self.true_init()
|
|
@@ -38,11 +73,23 @@ class AdvancedParameters(WindowType):
|
|
|
38
73
|
self.true_init()
|
|
39
74
|
|
|
40
75
|
def true_init(self):
|
|
76
|
+
"""
|
|
77
|
+
Initialize the AdvancedParameters window.
|
|
78
|
+
|
|
79
|
+
This method sets up the layout and widgets for the AdvancedParameters window,
|
|
80
|
+
including scroll areas, layouts, and various UI components for configuring
|
|
81
|
+
advanced parameters, including 'Cancel' and 'Ok' buttons.
|
|
82
|
+
|
|
83
|
+
Notes
|
|
84
|
+
-----
|
|
85
|
+
This method assumes that the parent widget has a 'po' attribute with specific settings and variables.
|
|
86
|
+
"""
|
|
87
|
+
logging.info("Initialize AdvancedParameters window")
|
|
41
88
|
self.layout = QtWidgets.QVBoxLayout()
|
|
42
89
|
|
|
43
|
-
self.left_scroll_table = QtWidgets.QScrollArea() #
|
|
90
|
+
self.left_scroll_table = QtWidgets.QScrollArea() # # Scroll Area which contains the widgets, set as the centralWidget
|
|
44
91
|
self.left_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
|
45
|
-
self.left_scroll_table.setMinimumHeight(150)
|
|
92
|
+
self.left_scroll_table.setMinimumHeight(150)
|
|
46
93
|
self.left_scroll_table.setFrameShape(QtWidgets.QFrame.NoFrame)
|
|
47
94
|
self.left_scroll_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
48
95
|
self.left_scroll_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
@@ -51,19 +98,11 @@ class AdvancedParameters(WindowType):
|
|
|
51
98
|
self.right_col_layout = QtWidgets.QVBoxLayout()
|
|
52
99
|
self.left_col_widget = QtWidgets.QWidget()
|
|
53
100
|
self.right_col_widget = QtWidgets.QWidget()
|
|
54
|
-
# curr_row_1st_col = 0
|
|
55
|
-
ncol = 11
|
|
56
101
|
# Create the main Title
|
|
57
102
|
self.title = FixedText('Advanced parameters', police=30, night_mode=self.parent().po.all['night_mode'])
|
|
58
103
|
self.title.setAlignment(QtCore.Qt.AlignHCenter)
|
|
59
104
|
# Create the main layout
|
|
60
105
|
self.layout.addWidget(self.title)
|
|
61
|
-
# self.layout.addItem(self.vertical_space)
|
|
62
|
-
# self.layout.addWidget(self.title, curr_row_1st_col, 0, 2, ncol)
|
|
63
|
-
# curr_row_1st_col += 2
|
|
64
|
-
# horzspaceItem = QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding)
|
|
65
|
-
# self.layout.addItem(horzspaceItem, 2, 0, 1, 5)
|
|
66
|
-
# curr_row_1st_col += 1
|
|
67
106
|
# Create the stylesheet for the boxes allowing to categorize advanced parameters.
|
|
68
107
|
boxstylesheet = \
|
|
69
108
|
".QWidget {\n" \
|
|
@@ -77,33 +116,32 @@ class AdvancedParameters(WindowType):
|
|
|
77
116
|
self.general_param_box_label = FixedText('General parameters:', tip="",
|
|
78
117
|
night_mode=self.parent().po.all['night_mode'])
|
|
79
118
|
self.left_col_layout.addWidget(self.general_param_box_label)
|
|
80
|
-
# self.layout.addWidget(self.general_param_box_label, curr_row_1st_col, 1)
|
|
81
|
-
# curr_row_1st_col += 1
|
|
82
119
|
# I/B/ Create the box
|
|
83
120
|
self.general_param_box_layout = QtWidgets.QGridLayout()
|
|
84
121
|
self.general_param_box_widget = QtWidgets.QWidget()
|
|
85
122
|
self.general_param_box_widget.setStyleSheet(boxstylesheet)
|
|
86
123
|
# I/C/ Create widgets
|
|
87
124
|
self.automatically_crop = Checkbox(self.parent().po.all['automatically_crop'])
|
|
88
|
-
self.automatically_crop_label = FixedText(
|
|
125
|
+
self.automatically_crop_label = FixedText(AP["Crop_images"]["label"], tip=AP["Crop_images"]["tips"],
|
|
126
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
89
127
|
|
|
90
128
|
self.subtract_background = Checkbox(self.parent().po.vars['subtract_background'])
|
|
91
129
|
self.subtract_background.stateChanged.connect(self.subtract_background_check)
|
|
92
|
-
self.subtract_background_label = FixedText(
|
|
130
|
+
self.subtract_background_label = FixedText(AP["Subtract_background"]["label"], tip=AP["Subtract_background"]["tips"], night_mode=self.parent().po.all['night_mode'])
|
|
93
131
|
|
|
94
132
|
self.keep_cell_and_back_for_all_folders = Checkbox(self.parent().po.all['keep_cell_and_back_for_all_folders'])
|
|
95
|
-
self.keep_cell_and_back_for_all_folders_label = FixedText(
|
|
96
|
-
tip="
|
|
133
|
+
self.keep_cell_and_back_for_all_folders_label = FixedText(AP["Keep_drawings"]["label"],
|
|
134
|
+
tip=AP["Keep_drawings"]["tips"],
|
|
97
135
|
night_mode=self.parent().po.all['night_mode'])
|
|
98
136
|
|
|
99
137
|
self.correct_errors_around_initial = Checkbox(self.parent().po.vars['correct_errors_around_initial'])
|
|
100
|
-
self.correct_errors_around_initial_label = FixedText(
|
|
101
|
-
tip="
|
|
138
|
+
self.correct_errors_around_initial_label = FixedText(AP["Correct_errors_around_initial"]["label"],
|
|
139
|
+
tip=AP["Correct_errors_around_initial"]["tips"],
|
|
102
140
|
night_mode=self.parent().po.all['night_mode'])
|
|
103
141
|
|
|
104
142
|
self.prevent_fast_growth_near_periphery = Checkbox(self.parent().po.vars['prevent_fast_growth_near_periphery'])
|
|
105
|
-
self.prevent_fast_growth_near_periphery_label = FixedText(
|
|
106
|
-
tip="
|
|
143
|
+
self.prevent_fast_growth_near_periphery_label = FixedText(AP["Prevent_fast_growth_near_periphery"]["label"],
|
|
144
|
+
tip=AP["Prevent_fast_growth_near_periphery"]["tips"],
|
|
107
145
|
night_mode=self.parent().po.all['night_mode'])
|
|
108
146
|
|
|
109
147
|
self.prevent_fast_growth_near_periphery.stateChanged.connect(self.prevent_fast_growth_near_periphery_check)
|
|
@@ -137,8 +175,6 @@ class AdvancedParameters(WindowType):
|
|
|
137
175
|
self.general_param_box_layout.addWidget(self.max_periphery_growth_label, 6, 1)
|
|
138
176
|
self.general_param_box_widget.setLayout(self.general_param_box_layout)
|
|
139
177
|
self.left_col_layout.addWidget(self.general_param_box_widget)
|
|
140
|
-
# self.layout.addWidget(self.general_param_box_widget, curr_row_1st_col, 1, 2, 2)
|
|
141
|
-
# curr_row_1st_col += 2
|
|
142
178
|
|
|
143
179
|
# II/ Second box: One cell/colony per arena
|
|
144
180
|
# II/A/ Title
|
|
@@ -153,16 +189,16 @@ class AdvancedParameters(WindowType):
|
|
|
153
189
|
# II/C/ Create widgets
|
|
154
190
|
self.all_specimens_have_same_direction = Checkbox(self.parent().po.all['all_specimens_have_same_direction'])
|
|
155
191
|
# self.all_specimens_have_same_direction.stateChanged.connect(self.all_specimens_have_same_direction_changed)
|
|
156
|
-
self.all_specimens_have_same_direction_label = FixedText(
|
|
157
|
-
tip="
|
|
192
|
+
self.all_specimens_have_same_direction_label = FixedText(AP["Specimens_have_same_direction"]["label"],
|
|
193
|
+
tip=AP["Specimens_have_same_direction"]["tips"],
|
|
158
194
|
night_mode=self.parent().po.all['night_mode'])
|
|
159
195
|
|
|
160
196
|
|
|
161
197
|
connect_distant_shape = self.parent().po.all['connect_distant_shape_during_segmentation']
|
|
162
198
|
self.connect_distant_shape_during_segmentation = Checkbox(connect_distant_shape)
|
|
163
199
|
self.connect_distant_shape_during_segmentation.stateChanged.connect(self.do_distant_shape_int_changed)
|
|
164
|
-
self.connect_distant_shape_label = FixedText(
|
|
165
|
-
tip="
|
|
200
|
+
self.connect_distant_shape_label = FixedText(AP["Connect_distant_shapes"]["label"],
|
|
201
|
+
tip=AP["Connect_distant_shapes"]["tips"],
|
|
166
202
|
night_mode=self.parent().po.all['night_mode'])
|
|
167
203
|
self.detection_range_factor = Spinbox(min=0, max=1000000,
|
|
168
204
|
val=self.parent().po.vars['detection_range_factor'],
|
|
@@ -201,22 +237,24 @@ class AdvancedParameters(WindowType):
|
|
|
201
237
|
else:
|
|
202
238
|
self.min_size_for_connection = Spinbox(min=0, max=1000000, val=0,
|
|
203
239
|
night_mode=self.parent().po.all['night_mode'])
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
# self.max_size_for_connection_label.setVisible(do_use_max_size)
|
|
214
|
-
# self.min_size_for_connection.setVisible(do_use_min_size)
|
|
215
|
-
# self.min_size_for_connection_label.setVisible(do_use_min_size)
|
|
216
|
-
|
|
217
|
-
self.use_min_size.setStyleSheet("margin-left:100%; margin-right:0%;")
|
|
240
|
+
|
|
241
|
+
self.use_min_size.setStyleSheet("QCheckBox::indicator {width: 12px;height: 12px;background-color: transparent;"
|
|
242
|
+
"border-radius: 5px;border-style: solid;border-width: 1px;"
|
|
243
|
+
"border-color: rgb(100,100,100);}"
|
|
244
|
+
"QCheckBox::indicator:checked {background-color: rgb(70,130,180);}"
|
|
245
|
+
"QCheckBox:checked, QCheckBox::indicator:checked {border-color: black black white white;}"
|
|
246
|
+
"QCheckBox:checked {background-color: transparent;}"
|
|
247
|
+
"QCheckBox:margin-left {100%}"
|
|
248
|
+
"QCheckBox:margin-right {0%}")
|
|
218
249
|
self.min_size_for_connection_label.setAlignment(QtCore.Qt.AlignRight)
|
|
219
|
-
self.use_max_size.setStyleSheet("
|
|
250
|
+
self.use_max_size.setStyleSheet("QCheckBox::indicator {width: 12px;height: 12px;background-color: transparent;"
|
|
251
|
+
"border-radius: 5px;border-style: solid;border-width: 1px;"
|
|
252
|
+
"border-color: rgb(100,100,100);}"
|
|
253
|
+
"QCheckBox::indicator:checked {background-color: rgb(70,130,180);}"
|
|
254
|
+
"QCheckBox:checked, QCheckBox::indicator:checked {border-color: black black white white;}"
|
|
255
|
+
"QCheckBox:checked {background-color: transparent;}"
|
|
256
|
+
"QCheckBox:margin-left {100%}"
|
|
257
|
+
"QCheckBox:margin-right {0%}")
|
|
220
258
|
self.max_size_for_connection_label.setAlignment(QtCore.Qt.AlignRight)
|
|
221
259
|
|
|
222
260
|
# II/D/ Arrange widgets in the box
|
|
@@ -245,8 +283,6 @@ class AdvancedParameters(WindowType):
|
|
|
245
283
|
|
|
246
284
|
self.one_per_arena_box_widget.setLayout(self.one_per_arena_box_layout)
|
|
247
285
|
self.left_col_layout.addWidget(self.one_per_arena_box_widget)
|
|
248
|
-
# self.layout.addWidget(self.one_per_arena_box_widget, curr_row_1st_col, 1, 3, 2)
|
|
249
|
-
# curr_row_1st_col += 2# curr_box_row
|
|
250
286
|
|
|
251
287
|
# III/ Third box: Appearing cell/colony
|
|
252
288
|
# III/A/ Title
|
|
@@ -254,8 +290,6 @@ class AdvancedParameters(WindowType):
|
|
|
254
290
|
night_mode=self.parent().po.all['night_mode'])
|
|
255
291
|
|
|
256
292
|
self.left_col_layout.addWidget(self.appearing_cell_label)
|
|
257
|
-
# self.layout.addWidget(self.appearing_cell_label, curr_row_1st_col, 1)
|
|
258
|
-
# curr_row_1st_col += 1
|
|
259
293
|
# III/B/ Create the box
|
|
260
294
|
self.appearing_cell_box_layout = QtWidgets.QGridLayout()
|
|
261
295
|
self.appearing_cell_box_widget = QtWidgets.QWidget()
|
|
@@ -267,15 +301,14 @@ class AdvancedParameters(WindowType):
|
|
|
267
301
|
self.first_move_threshold_label = FixedText('Minimal size to detect a cell/colony',
|
|
268
302
|
tip="In mm². All appearing cell/colony lesser than this value will be considered as noise",
|
|
269
303
|
night_mode=self.parent().po.all['night_mode'])
|
|
270
|
-
# self.first_move_threshold.setVisible(not self.parent().po.all['automatic_size_thresholding'])
|
|
271
|
-
# self.first_move_threshold_label.setVisible(not self.parent().po.all['automatic_size_thresholding'])
|
|
272
304
|
self.do_automatic_size_thresholding = Checkbox(self.parent().po.all['automatic_size_thresholding'])
|
|
273
|
-
self.do_automatic_size_thresholding_label = FixedText(
|
|
305
|
+
self.do_automatic_size_thresholding_label = FixedText(AP["Appearance_size_threshold"]["label"],
|
|
306
|
+
tip=AP["Appearance_size_threshold"]["tips"],
|
|
274
307
|
night_mode=self.parent().po.all['night_mode'])
|
|
275
308
|
self.do_automatic_size_thresholding.stateChanged.connect(self.do_automatic_size_thresholding_changed)
|
|
276
309
|
self.appearing_selection = Combobox(["largest", "most_central"], night_mode=self.parent().po.all['night_mode'])
|
|
277
|
-
self.appearing_selection_label = FixedText(
|
|
278
|
-
tip="
|
|
310
|
+
self.appearing_selection_label = FixedText(AP["Appearance_detection_method"]["label"],
|
|
311
|
+
tip=AP["Appearance_detection_method"]["tips"],
|
|
279
312
|
night_mode=self.parent().po.all['night_mode'])
|
|
280
313
|
self.appearing_selection.setCurrentText(self.parent().po.vars['appearance_detection_method'])
|
|
281
314
|
self.appearing_selection.setFixedWidth(190)
|
|
@@ -294,10 +327,70 @@ class AdvancedParameters(WindowType):
|
|
|
294
327
|
|
|
295
328
|
self.appearing_cell_box_widget.setLayout(self.appearing_cell_box_layout)
|
|
296
329
|
self.left_col_layout.addWidget(self.appearing_cell_box_widget)
|
|
297
|
-
# self.layout.addWidget(self.appearing_cell_box_widget, curr_row_1st_col, 1, 2, 2)
|
|
298
|
-
# curr_row_1st_col += curr_box_row
|
|
299
330
|
|
|
300
|
-
#
|
|
331
|
+
# V/ Fifth box: Network detection parameters:#
|
|
332
|
+
# IV/A/ Title
|
|
333
|
+
self.rolling_window_s_label = FixedText(IAW["Rolling_window_segmentation"]["label"] + ': (auto if checked)',
|
|
334
|
+
tip=IAW["Rolling_window_segmentation"]["tips"],
|
|
335
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
336
|
+
self.left_col_layout.addWidget(self.rolling_window_s_label)
|
|
337
|
+
self.rolling_window_s_layout = QtWidgets.QGridLayout()
|
|
338
|
+
self.rolling_window_s_widget = QtWidgets.QWidget()
|
|
339
|
+
self.rolling_window_s_widget.setStyleSheet(boxstylesheet)
|
|
340
|
+
self.mesh_side_length_cb = Checkbox(self.parent().po.all['auto_mesh_side_length'],
|
|
341
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
342
|
+
self.mesh_side_length_cb.stateChanged.connect(self.mesh_side_length_cb_changed)
|
|
343
|
+
self.mesh_side_length_label = FixedText(AP["Mesh_side_length"]["label"], tip=AP["Mesh_side_length"]["tips"],
|
|
344
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
345
|
+
if self.parent().po.vars['rolling_window_segmentation']['side_len'] is None:
|
|
346
|
+
self.mesh_side_length = Spinbox(min=0, max=1000000, val=4, decimals=0,
|
|
347
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
348
|
+
self.mesh_side_length.setVisible(False)
|
|
349
|
+
else:
|
|
350
|
+
self.mesh_side_length = Spinbox(min=0, max=1000000, val=self.parent().po.vars['rolling_window_segmentation']['side_len'], decimals=0,
|
|
351
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
self.mesh_step_length_cb = Checkbox(self.parent().po.all['auto_mesh_step_length'],
|
|
355
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
356
|
+
self.mesh_step_length_cb.stateChanged.connect(self.mesh_step_length_cb_changed)
|
|
357
|
+
self.mesh_step_length_label = FixedText(AP["Mesh_step_length"]["label"], tip=AP["Mesh_step_length"]["tips"],
|
|
358
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
359
|
+
if self.parent().po.vars['rolling_window_segmentation']['side_len'] is None:
|
|
360
|
+
self.mesh_step_length = Spinbox(min=0, max=1000, val=2, decimals=0,
|
|
361
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
362
|
+
self.mesh_step_length.setVisible(False)
|
|
363
|
+
else:
|
|
364
|
+
self.mesh_step_length = Spinbox(min=0, max=1000, val=self.parent().po.vars['rolling_window_segmentation']['step'], decimals=0,
|
|
365
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
self.mesh_min_int_var_cb = Checkbox(self.parent().po.all['auto_mesh_min_int_var'],
|
|
369
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
370
|
+
self.mesh_min_int_var_cb.stateChanged.connect(self.mesh_min_int_var_cb_changed)
|
|
371
|
+
if self.parent().po.vars['rolling_window_segmentation']['side_len'] is None:
|
|
372
|
+
self.mesh_min_int_var = Spinbox(min=0, max=1000, val=2, decimals=0,
|
|
373
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
374
|
+
self.mesh_min_int_var.setVisible(False)
|
|
375
|
+
else:
|
|
376
|
+
self.mesh_min_int_var = Spinbox(min=0, max=1000, val=self.parent().po.vars['rolling_window_segmentation']['min_int_var'], decimals=0,
|
|
377
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
378
|
+
self.mesh_min_int_var_label = FixedText(AP["Mesh_minimal_intensity_variation"]["label"],
|
|
379
|
+
tip=AP["Mesh_minimal_intensity_variation"]["tips"],
|
|
380
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
381
|
+
self.rolling_window_s_layout.addWidget(self.mesh_side_length_cb, 0, 0)
|
|
382
|
+
self.rolling_window_s_layout.addWidget(self.mesh_side_length_label, 0, 1)
|
|
383
|
+
self.rolling_window_s_layout.addWidget(self.mesh_side_length, 0, 2)
|
|
384
|
+
self.rolling_window_s_layout.addWidget(self.mesh_step_length_cb, 1, 0)
|
|
385
|
+
self.rolling_window_s_layout.addWidget(self.mesh_step_length_label, 1, 1)
|
|
386
|
+
self.rolling_window_s_layout.addWidget(self.mesh_step_length, 1, 2)
|
|
387
|
+
self.rolling_window_s_layout.addWidget(self.mesh_min_int_var_cb, 2, 0)
|
|
388
|
+
self.rolling_window_s_layout.addWidget(self.mesh_min_int_var_label, 2, 1)
|
|
389
|
+
self.rolling_window_s_layout.addWidget(self.mesh_min_int_var, 2, 2)
|
|
390
|
+
self.rolling_window_s_widget.setLayout(self.rolling_window_s_layout)
|
|
391
|
+
self.left_col_layout.addWidget(self.rolling_window_s_widget)
|
|
392
|
+
|
|
393
|
+
# IV/ Fourth box: Oscillation period:
|
|
301
394
|
# IV/A/ Title
|
|
302
395
|
self.oscillation_label = FixedText('Oscillatory parameters:', tip="",
|
|
303
396
|
night_mode=self.parent().po.all['night_mode'])
|
|
@@ -309,14 +402,14 @@ class AdvancedParameters(WindowType):
|
|
|
309
402
|
|
|
310
403
|
self.oscillation_period = Spinbox(min=0, max=10000, val=self.parent().po.vars['expected_oscillation_period'], decimals=2,
|
|
311
404
|
night_mode=self.parent().po.all['night_mode'])
|
|
312
|
-
self.oscillation_period_label = FixedText(
|
|
313
|
-
tip="
|
|
405
|
+
self.oscillation_period_label = FixedText(AP["Expected_oscillation_period"]["label"],
|
|
406
|
+
tip=AP["Expected_oscillation_period"]["tips"],
|
|
314
407
|
night_mode=self.parent().po.all['night_mode'])
|
|
315
408
|
|
|
316
409
|
self.minimal_oscillating_cluster_size = Spinbox(min=1, max=1000000000, decimals=0, val=self.parent().po.vars['minimal_oscillating_cluster_size'],
|
|
317
410
|
night_mode=self.parent().po.all['night_mode'])
|
|
318
|
-
self.minimal_oscillating_cluster_size_label = FixedText(
|
|
319
|
-
tip="
|
|
411
|
+
self.minimal_oscillating_cluster_size_label = FixedText(AP["Minimal_oscillating_cluster_size"]["label"],
|
|
412
|
+
tip=AP["Minimal_oscillating_cluster_size"]["tips"],
|
|
320
413
|
night_mode=self.parent().po.all['night_mode'])
|
|
321
414
|
|
|
322
415
|
self.oscillation_period_layout.addWidget(self.oscillation_period, 0, 0)
|
|
@@ -327,109 +420,27 @@ class AdvancedParameters(WindowType):
|
|
|
327
420
|
self.oscillation_period_widget.setLayout(self.oscillation_period_layout)
|
|
328
421
|
self.left_col_layout.addWidget(self.oscillation_period_widget)
|
|
329
422
|
|
|
330
|
-
|
|
331
|
-
# V/ Fifth box: Fractal parameters:#
|
|
332
|
-
# IV/A/ Title
|
|
333
|
-
# self.fractal_label = FixedText('Fractal parameters:', tip="",
|
|
334
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
335
|
-
# self.left_col_layout.addWidget(self.fractal_label)
|
|
336
|
-
#
|
|
337
|
-
# self.fractal_layout = QtWidgets.QGridLayout()
|
|
338
|
-
# self.fractal_widget = QtWidgets.QWidget()
|
|
339
|
-
# self.fractal_widget.setStyleSheet(boxstylesheet)
|
|
340
|
-
#
|
|
341
|
-
# self.fractal_box_side_threshold = Spinbox(min=0, max=100000, val=self.parent().po.vars['fractal_box_side_threshold'], decimals=0,
|
|
342
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
343
|
-
# self.fractal_box_side_threshold_label = FixedText('Fractal box side threshold',
|
|
344
|
-
# tip="Increase/decrease to adjust the minimal side length (pixels) of an image\nto compute the Minkowski dimension using the box counting method.",
|
|
345
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
346
|
-
# self.fractal_layout.addWidget(self.fractal_box_side_threshold, 3, 0)
|
|
347
|
-
# self.fractal_layout.addWidget(self.fractal_box_side_threshold_label, 3, 1)
|
|
348
|
-
# self.fractal_zoom_step = Spinbox(min=0, max=100000, val=self.parent().po.vars['fractal_zoom_step'], decimals=0,
|
|
349
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
350
|
-
# self.fractal_zoom_step_label = FixedText('Fractal zoom step',
|
|
351
|
-
# tip="When using the box counting method to compute the Minkowski dimension\nThe zoom step is the side length (pixels) difference between each zoom level.\nWhen set to 0, the default zoom step is all possible powers of two.",
|
|
352
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
353
|
-
# self.fractal_layout.addWidget(self.fractal_zoom_step, 4, 0)
|
|
354
|
-
# self.fractal_layout.addWidget(self.fractal_zoom_step_label, 4, 1)
|
|
355
|
-
#
|
|
356
|
-
# self.fractal_widget.setLayout(self.fractal_layout)
|
|
357
|
-
# self.left_col_layout.addWidget(self.fractal_widget)
|
|
358
|
-
|
|
359
|
-
# V/ Fifth box: Network detection parameters:#
|
|
360
|
-
# IV/A/ Title
|
|
361
|
-
self.network_label = FixedText('Network parameters:', tip="",
|
|
362
|
-
night_mode=self.parent().po.all['night_mode'])
|
|
363
|
-
self.left_col_layout.addWidget(self.network_label)
|
|
364
|
-
|
|
365
|
-
self.network_layout = QtWidgets.QGridLayout()
|
|
366
|
-
self.network_widget = QtWidgets.QWidget()
|
|
367
|
-
self.network_widget.setStyleSheet(boxstylesheet)
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
self.network_detection_threshold = Spinbox(min=0, max=255, val=self.parent().po.vars['network_detection_threshold'], decimals=0,
|
|
371
|
-
night_mode=self.parent().po.all['night_mode'])
|
|
372
|
-
self.network_detection_threshold_label = FixedText('Network detection threshold',
|
|
373
|
-
tip="To detect the network, Cellects segment small parts of the image using a sliding window.\nThis threshold is an intensity value [0, 255]\napplied to the sliding window to not consider homogeneous substes of the image\ni.e. This is the minimal variation in intensity to consider that some pixels are parts of the network.",
|
|
374
|
-
night_mode=self.parent().po.all['night_mode'])
|
|
375
|
-
# self.mesh_side_length = Spinbox(min=2, max=1000000, val=self.parent().po.vars['network_mesh_side_length'], decimals=0,
|
|
376
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
377
|
-
# self.mesh_side_length_label = FixedText('Mesh side length',
|
|
378
|
-
# tip="This is the side length (in pixels) of the sliding window used to detect the network.\nHigh values are faster but less precise.\nWhen too high, straight vertical or horizontal lines appear in the detected network.",
|
|
379
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
380
|
-
# self.mesh_step_length = Spinbox(min=1, max=100, val=self.parent().po.vars['network_mesh_step_length'], decimals=0,
|
|
381
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
382
|
-
# self.mesh_step_length_label = FixedText('Mesh step length',
|
|
383
|
-
# tip="This is the distance (in pixels) travelled by the sliding window\n(used to detect the network) at each stage.\nHigh values are faster but less precise.",
|
|
384
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
385
|
-
|
|
386
|
-
self.network_layout.addWidget(self.network_detection_threshold, 0, 0)
|
|
387
|
-
self.network_layout.addWidget(self.network_detection_threshold_label, 0, 1)
|
|
388
|
-
# self.network_layout.addWidget(self.mesh_side_length, 1, 0)
|
|
389
|
-
# self.network_layout.addWidget(self.mesh_side_length_label, 1, 1)
|
|
390
|
-
# self.network_layout.addWidget(self.mesh_step_length, 2, 0)
|
|
391
|
-
# self.network_layout.addWidget(self.mesh_step_length_label, 2, 1)
|
|
392
|
-
|
|
393
|
-
self.network_widget.setLayout(self.network_layout)
|
|
394
|
-
self.left_col_layout.addWidget(self.network_widget)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
# self.layout.addWidget(self.oscillation_period_widget, curr_row_1st_col, 1)
|
|
398
|
-
# curr_row_1st_col + 1
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
# From here start the 2nd column of boxes in the advanced parameters window
|
|
402
|
-
# vertspaceItem = QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding,
|
|
403
|
-
# QtWidgets.QSizePolicy.Maximum)
|
|
404
|
-
# self.layout.addItem(vertspaceItem, 0, 3, 10, 1)
|
|
405
|
-
# curr_row_2nd_col = 3
|
|
406
|
-
|
|
407
|
-
|
|
408
423
|
# I/ First box: Scales
|
|
409
424
|
# I/A/ Title
|
|
410
|
-
|
|
411
|
-
self.right_scroll_table = QtWidgets.QScrollArea() # QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
|
|
425
|
+
self.right_scroll_table = QtWidgets.QScrollArea() # Scroll Area which contains the widgets, set as the centralWidget
|
|
412
426
|
self.right_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
|
413
427
|
self.right_scroll_table.setMinimumHeight(150)#self.parent().im_max_height - 100
|
|
414
428
|
self.right_scroll_table.setFrameShape(QtWidgets.QFrame.NoFrame)
|
|
415
429
|
self.right_scroll_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
416
430
|
self.right_scroll_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
self.scale_box_label = FixedText('Spatio-temporal scaling:', tip="",
|
|
431
|
+
self.scale_box_label = FixedText(AP["Spatio_temporal_scaling"]["label"] + ':',
|
|
432
|
+
tip=AP["Spatio_temporal_scaling"]["tips"],
|
|
420
433
|
night_mode=self.parent().po.all['night_mode'])
|
|
421
434
|
self.right_col_layout.addWidget(self.scale_box_label)
|
|
422
|
-
|
|
423
|
-
# curr_row_2nd_col += 1
|
|
435
|
+
|
|
424
436
|
# I/B/ Create the box
|
|
425
437
|
self.scale_box_layout = QtWidgets.QGridLayout()
|
|
426
438
|
self.scale_box_widget = QtWidgets.QWidget()
|
|
427
439
|
self.scale_box_widget.setStyleSheet(boxstylesheet)
|
|
428
|
-
# I/C/ Create widgets
|
|
429
440
|
|
|
441
|
+
# I/C/ Create widgets
|
|
430
442
|
self.extract_time = Checkbox(self.parent().po.all['extract_time_interval'])
|
|
431
443
|
self.extract_time.clicked.connect(self.extract_time_is_clicked)
|
|
432
|
-
|
|
433
444
|
self.time_step = Spinbox(min=0, max=100000, val=self.parent().po.vars['time_step'], decimals=3,
|
|
434
445
|
night_mode=self.parent().po.all['night_mode'])
|
|
435
446
|
self.time_step.setFixedWidth(60)
|
|
@@ -442,35 +453,25 @@ class AdvancedParameters(WindowType):
|
|
|
442
453
|
self.time_step_label = FixedText('Set the time interval between images',
|
|
443
454
|
tip="In minutes",
|
|
444
455
|
night_mode=self.parent().po.all['night_mode'])
|
|
445
|
-
# self.overwrite_cellects_data = Checkbox(self.parent().po.all['overwrite_cellects_data'],
|
|
446
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
447
|
-
# self.overwrite_cellects_data_label = FixedText('Do overwrite cellects data',
|
|
448
|
-
# tip="The file Data to run Cellects quickly.pkl allow to run\na complete analysis from the first and the video anaysis window",
|
|
449
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
450
456
|
self.pixels_to_mm = Checkbox(self.parent().po.vars['output_in_mm'])
|
|
451
457
|
self.pixels_to_mm_label = FixedText('Convert areas and distances from pixels to mm',
|
|
452
458
|
tip="Check if you want output variables to be in mm\nUncheck if you want output variables to be in pixels",
|
|
453
459
|
night_mode=self.parent().po.all['night_mode'])
|
|
460
|
+
|
|
454
461
|
# I/D/ Arrange widgets in the box
|
|
455
462
|
self.scale_box_layout.addWidget(self.extract_time, 0, 0)
|
|
456
463
|
self.scale_box_layout.addWidget(self.time_step_label, 0, 1)
|
|
457
464
|
self.scale_box_layout.addWidget(self.time_step, 0, 2)
|
|
458
|
-
# self.scale_box_layout.addWidget(self.overwrite_cellects_data, 1, 0)
|
|
459
|
-
# self.scale_box_layout.addWidget(self.overwrite_cellects_data_label, 1, 1)
|
|
460
465
|
self.scale_box_layout.addWidget(self.pixels_to_mm, 2, 0)
|
|
461
466
|
self.scale_box_layout.addWidget(self.pixels_to_mm_label, 2, 1)
|
|
462
467
|
self.scale_box_widget.setLayout(self.scale_box_layout)
|
|
463
468
|
self.right_col_layout.addWidget(self.scale_box_widget)
|
|
464
|
-
# self.layout.addWidget(self.scale_box_widget, curr_row_2nd_col, 4, 2, 2)
|
|
465
|
-
# curr_row_2nd_col += 3
|
|
466
469
|
|
|
467
470
|
# IV/ Fourth box: Computer resources
|
|
468
471
|
# IV/A/ Title
|
|
469
472
|
self.resources_label = FixedText('Computer resources:', tip="",
|
|
470
473
|
night_mode=self.parent().po.all['night_mode'])
|
|
471
474
|
self.right_col_layout.addWidget(self.resources_label)
|
|
472
|
-
# self.layout.addWidget(self.resources_label, curr_row_2nd_col, 4)
|
|
473
|
-
# curr_row_2nd_col += 1
|
|
474
475
|
|
|
475
476
|
# IV/B/ Create the box
|
|
476
477
|
self.resources_box_layout = QtWidgets.QGridLayout()
|
|
@@ -479,21 +480,23 @@ class AdvancedParameters(WindowType):
|
|
|
479
480
|
|
|
480
481
|
# IV/C/ Create widgets
|
|
481
482
|
self.do_multiprocessing = Checkbox(self.parent().po.all['do_multiprocessing'])
|
|
482
|
-
self.do_multiprocessing_label = FixedText(
|
|
483
|
+
self.do_multiprocessing_label = FixedText(AP["Parallel_analysis"]["label"], tip=AP["Parallel_analysis"]["tips"],
|
|
484
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
483
485
|
self.do_multiprocessing.stateChanged.connect(self.do_multiprocessing_is_clicked)
|
|
484
486
|
self.max_core_nb = Spinbox(min=0, max=256, val=self.parent().po.all['cores'],
|
|
485
487
|
night_mode=self.parent().po.all['night_mode'])
|
|
486
|
-
self.max_core_nb_label = FixedText(
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
488
|
+
self.max_core_nb_label = FixedText(AP["Proc_max_core_nb"]["label"],
|
|
489
|
+
tip=AP["Proc_max_core_nb"]["tips"],
|
|
490
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
490
491
|
self.min_memory_left = Spinbox(min=0, max=1024, val=self.parent().po.vars['min_ram_free'], decimals=1,
|
|
491
492
|
night_mode=self.parent().po.all['night_mode'])
|
|
492
|
-
self.min_memory_left_label = FixedText(
|
|
493
|
+
self.min_memory_left_label = FixedText(AP["Minimal_RAM_let_free"]["label"],
|
|
494
|
+
tip=AP["Minimal_RAM_let_free"]["tips"],
|
|
495
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
493
496
|
|
|
494
497
|
self.lose_accuracy_to_save_memory = Checkbox(self.parent().po.vars['lose_accuracy_to_save_memory'])
|
|
495
|
-
self.lose_accuracy_to_save_memory_label = FixedText(
|
|
496
|
-
tip="
|
|
498
|
+
self.lose_accuracy_to_save_memory_label = FixedText(AP["Lose_accuracy_to_save_RAM"]["label"],
|
|
499
|
+
tip=AP["Lose_accuracy_to_save_RAM"]["tips"],
|
|
497
500
|
night_mode=self.parent().po.all['night_mode'])
|
|
498
501
|
|
|
499
502
|
# IV/D/ Arrange widgets in the box
|
|
@@ -507,16 +510,13 @@ class AdvancedParameters(WindowType):
|
|
|
507
510
|
self.resources_box_layout.addWidget(self.lose_accuracy_to_save_memory_label, 3, 1)
|
|
508
511
|
self.resources_box_widget.setLayout(self.resources_box_layout)
|
|
509
512
|
self.right_col_layout.addWidget(self.resources_box_widget)
|
|
510
|
-
# self.layout.addWidget(self.resources_box_widget, curr_row_2nd_col, 4, 2, 2)
|
|
511
|
-
# curr_row_2nd_col += 3
|
|
512
513
|
|
|
513
514
|
# V/ Fifth box: Video saving
|
|
514
515
|
# V/A/ Title
|
|
515
516
|
self.video_saving_label = FixedText('Video saving:', tip="",
|
|
516
517
|
night_mode=self.parent().po.all['night_mode'])
|
|
517
518
|
self.right_col_layout.addWidget(self.video_saving_label)
|
|
518
|
-
|
|
519
|
-
# curr_row_2nd_col += 1
|
|
519
|
+
|
|
520
520
|
# V/B/ Create the box
|
|
521
521
|
self.video_saving_layout = QtWidgets.QGridLayout()
|
|
522
522
|
self.video_saving_widget = QtWidgets.QWidget()
|
|
@@ -525,82 +525,67 @@ class AdvancedParameters(WindowType):
|
|
|
525
525
|
# V/C/ Create widgets
|
|
526
526
|
self.video_fps = Spinbox(min=0, max=10000, val=self.parent().po.vars['video_fps'], decimals=2,
|
|
527
527
|
night_mode=self.parent().po.all['night_mode'])
|
|
528
|
-
self.video_fps_label = FixedText(
|
|
529
|
-
|
|
530
|
-
# self.overwrite_unaltered_videos_label = FixedText('Do overwrite unaltered videos (.npy)', tip="If the analysis fails because of a bad detection of arenas\nChecking this may resolve failures during image analysis", night_mode=self.parent().po.all['night_mode'])
|
|
528
|
+
self.video_fps_label = FixedText(AP["Video_fps"]["label"], tip=AP["Video_fps"]["tips"],
|
|
529
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
531
530
|
self.keep_unaltered_videos = Checkbox(self.parent().po.vars['keep_unaltered_videos'])
|
|
532
|
-
self.keep_unaltered_videos_label = FixedText(
|
|
531
|
+
self.keep_unaltered_videos_label = FixedText(AP["Keep_unaltered_videos"]["label"],
|
|
532
|
+
tip=AP["Keep_unaltered_videos"]["tips"],
|
|
533
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
533
534
|
self.save_processed_videos = Checkbox(self.parent().po.vars['save_processed_videos'])
|
|
534
|
-
self.save_processed_videos_label = FixedText(
|
|
535
|
+
self.save_processed_videos_label = FixedText(AP["Save_processed_videos"]["label"],
|
|
536
|
+
tip=AP["Save_processed_videos"]["tips"],
|
|
537
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
535
538
|
|
|
536
539
|
# V/D/ Arrange widgets in the box
|
|
537
540
|
curr_box_row = 0
|
|
538
541
|
self.video_saving_layout.addWidget(self.video_fps, curr_box_row, 0)
|
|
539
542
|
self.video_saving_layout.addWidget(self.video_fps_label, curr_box_row, 1)
|
|
540
543
|
curr_box_row += 1
|
|
541
|
-
# self.video_saving_layout.addWidget(self.overwrite_unaltered_videos, curr_box_row, 0)
|
|
542
|
-
# self.video_saving_layout.addWidget(self.overwrite_unaltered_videos_label, curr_box_row, 1)
|
|
543
|
-
# curr_box_row += 1
|
|
544
544
|
self.video_saving_layout.addWidget(self.keep_unaltered_videos, curr_box_row, 0)
|
|
545
545
|
self.video_saving_layout.addWidget(self.keep_unaltered_videos_label, curr_box_row, 1)
|
|
546
546
|
curr_box_row += 1
|
|
547
547
|
self.video_saving_layout.addWidget(self.save_processed_videos, curr_box_row, 0)
|
|
548
548
|
self.video_saving_layout.addWidget(self.save_processed_videos_label, curr_box_row, 1)
|
|
549
549
|
curr_box_row += 1
|
|
550
|
-
|
|
551
550
|
self.video_saving_widget.setLayout(self.video_saving_layout)
|
|
552
551
|
self.right_col_layout.addWidget(self.video_saving_widget)
|
|
553
|
-
# self.layout.addWidget(self.video_saving_widget, curr_row_2nd_col, 4, 2, 2)
|
|
554
|
-
# curr_row_2nd_col += 2
|
|
555
552
|
|
|
556
553
|
# VII/ Seventh box: csc
|
|
557
554
|
# VII/A/ Title
|
|
558
|
-
# self.video_csc_label = FixedText('Color space combination for video analysis:', tip="",
|
|
559
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
560
|
-
# self.right_col_layout.addWidget(self.video_csc_label)
|
|
561
|
-
# self.layout.addWidget(self.video_csc_label, curr_row_2nd_col, 4)
|
|
562
|
-
# curr_row_2nd_col += 1
|
|
563
|
-
|
|
564
555
|
# VII/C/ Create widgets
|
|
565
556
|
self.generate_csc_editing()
|
|
566
557
|
# VII/D/ Arrange widgets in the box
|
|
567
558
|
self.right_col_layout.addWidget(self.edit_widget)
|
|
568
|
-
# self.layout.addWidget(self.edit_widget, curr_row_2nd_col, 4, 2, 2)
|
|
569
|
-
# curr_row_2nd_col += 3
|
|
570
559
|
|
|
571
560
|
# VIII/ Finalize layout and add the night mode option and the ok button
|
|
572
561
|
self.left_col_layout.addItem(self.vertical_space)
|
|
573
562
|
self.right_col_layout.addItem(self.vertical_space)
|
|
574
563
|
self.left_col_widget.setLayout(self.left_col_layout)
|
|
575
|
-
|
|
576
|
-
|
|
577
564
|
self.right_col_widget.setLayout(self.right_col_layout)
|
|
578
565
|
self.central_layout = QtWidgets.QHBoxLayout()
|
|
579
566
|
self.central_layout.addItem(self.horizontal_space)
|
|
580
|
-
#self.central_layout.addWidget(self.left_col_widget)
|
|
581
|
-
|
|
582
567
|
self.left_scroll_table.setWidget(self.left_col_widget)
|
|
583
568
|
self.left_scroll_table.setWidgetResizable(True)
|
|
584
569
|
self.central_layout.addWidget(self.left_scroll_table)
|
|
585
|
-
|
|
586
|
-
|
|
587
570
|
self.central_layout.addItem(self.horizontal_space)
|
|
588
571
|
self.right_scroll_table.setWidget(self.right_col_widget)
|
|
589
572
|
self.right_scroll_table.setWidgetResizable(True)
|
|
590
573
|
self.central_layout.addWidget(self.right_scroll_table)
|
|
591
|
-
# self.central_layout.addWidget(self.right_col_widget)
|
|
592
574
|
self.central_layout.addItem(self.horizontal_space)
|
|
593
575
|
self.central_widget = QtWidgets.QWidget()
|
|
594
576
|
self.central_widget.setLayout(self.central_layout)
|
|
595
577
|
self.layout.addWidget(self.central_widget)
|
|
596
|
-
self.layout.addItem(self.vertical_space)
|
|
578
|
+
# self.layout.addItem(self.vertical_space)
|
|
579
|
+
|
|
597
580
|
# Last row
|
|
598
581
|
self.last_row_layout = QtWidgets.QHBoxLayout()
|
|
599
582
|
self.last_row_widget = QtWidgets.QWidget()
|
|
600
583
|
self.night_mode_cb = Checkbox(self.parent().po.all['night_mode'])
|
|
601
584
|
self.night_mode_cb.clicked.connect(self.night_mode_is_clicked)
|
|
602
|
-
self.night_mode_label = FixedText(
|
|
603
|
-
|
|
585
|
+
self.night_mode_label = FixedText(AP["Night_mode"]["label"], tip=AP["Night_mode"]["tips"],
|
|
586
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
587
|
+
self.reset_all_settings = PButton(AP["Reset_all_settings"]["label"], tip=AP["Reset_all_settings"]["tips"],
|
|
588
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
604
589
|
self.reset_all_settings.clicked.connect(self.reset_all_settings_is_clicked)
|
|
605
590
|
self.message = FixedText('', night_mode=self.parent().po.all['night_mode'])
|
|
606
591
|
self.cancel = PButton('Cancel', night_mode=self.parent().po.all['night_mode'])
|
|
@@ -620,6 +605,13 @@ class AdvancedParameters(WindowType):
|
|
|
620
605
|
self.setLayout(self.layout)
|
|
621
606
|
|
|
622
607
|
def display_conditionally_visible_widgets(self):
|
|
608
|
+
"""
|
|
609
|
+
Conditionally displays widgets based on various settings within the parent object.
|
|
610
|
+
|
|
611
|
+
This function controls the visibility of several UI elements based on the
|
|
612
|
+
values in the parent object's `all` dictionary and `vars` dictionary. It ensures
|
|
613
|
+
that only relevant widgets are shown to the user, depending on the current settings.
|
|
614
|
+
"""
|
|
623
615
|
self.max_core_nb.setVisible(self.parent().po.all['do_multiprocessing'])
|
|
624
616
|
self.max_core_nb_label.setVisible(self.parent().po.all['do_multiprocessing'])
|
|
625
617
|
self.first_move_threshold.setVisible(not self.parent().po.all['automatic_size_thresholding'])
|
|
@@ -649,11 +641,17 @@ class AdvancedParameters(WindowType):
|
|
|
649
641
|
self.row21[3].setValue(0)
|
|
650
642
|
|
|
651
643
|
def subtract_background_check(self):
|
|
644
|
+
"""
|
|
645
|
+
Handles the logic for using background subtraction or not during image segmentation.
|
|
646
|
+
"""
|
|
652
647
|
self.parent().po.motion = None
|
|
653
648
|
if self.subtract_background.isChecked():
|
|
654
649
|
self.parent().po.first_exp_ready_to_run = False
|
|
655
650
|
|
|
656
651
|
def prevent_fast_growth_near_periphery_check(self):
|
|
652
|
+
"""
|
|
653
|
+
Handles the logic for using a special algorithm on growth near the periphery during video segmentation.
|
|
654
|
+
"""
|
|
657
655
|
checked_status = self.prevent_fast_growth_near_periphery.isChecked()
|
|
658
656
|
self.periphery_width.setVisible(checked_status)
|
|
659
657
|
self.periphery_width_label.setVisible(checked_status)
|
|
@@ -661,11 +659,28 @@ class AdvancedParameters(WindowType):
|
|
|
661
659
|
self.max_periphery_growth_label.setVisible(checked_status)
|
|
662
660
|
|
|
663
661
|
def do_automatic_size_thresholding_changed(self):
|
|
664
|
-
"""
|
|
662
|
+
"""
|
|
663
|
+
This function toggles the visibility of `first_move_threshold` and
|
|
664
|
+
`first_move_threshold_label` UI elements based on whether the
|
|
665
|
+
`do_automatic_size_thresholding` checkbox is checked or not.
|
|
666
|
+
"""
|
|
665
667
|
self.first_move_threshold.setVisible(not self.do_automatic_size_thresholding.isChecked())
|
|
666
668
|
self.first_move_threshold_label.setVisible(not self.do_automatic_size_thresholding.isChecked())
|
|
667
669
|
|
|
670
|
+
def mesh_side_length_cb_changed(self):
|
|
671
|
+
self.mesh_side_length.setVisible(self.mesh_side_length_cb.isChecked())
|
|
672
|
+
|
|
673
|
+
def mesh_step_length_cb_changed(self):
|
|
674
|
+
self.mesh_step_length.setVisible(self.mesh_step_length_cb.isChecked())
|
|
675
|
+
|
|
676
|
+
def mesh_min_int_var_cb_changed(self):
|
|
677
|
+
self.mesh_min_int_var.setVisible(self.mesh_min_int_var_cb.isChecked())
|
|
678
|
+
|
|
668
679
|
def extract_time_is_clicked(self):
|
|
680
|
+
"""
|
|
681
|
+
Toggle the visibility of time_step_label and update its text/tooltip based on
|
|
682
|
+
whether extract_time is checked.
|
|
683
|
+
"""
|
|
669
684
|
self.time_step.setVisible(not self.extract_time.isChecked())
|
|
670
685
|
if self.extract_time.isChecked():
|
|
671
686
|
self.time_step_label.setText("Automatically extract time interval between images")
|
|
@@ -675,15 +690,17 @@ class AdvancedParameters(WindowType):
|
|
|
675
690
|
self.time_step_label.setToolTip("In minutes")
|
|
676
691
|
|
|
677
692
|
def do_multiprocessing_is_clicked(self):
|
|
693
|
+
"""
|
|
694
|
+
Update the visibility of `max_core_nb` and `max_core_nb_label` based on the checkbox state of `do_multiprocessing`.
|
|
695
|
+
"""
|
|
678
696
|
self.max_core_nb.setVisible(self.do_multiprocessing.isChecked())
|
|
679
697
|
self.max_core_nb_label.setVisible(self.do_multiprocessing.isChecked())
|
|
680
698
|
|
|
681
|
-
# def all_specimens_have_same_direction_changed(self):
|
|
682
|
-
# """ Triggered when all_specimens_have_same_direction check status changes"""
|
|
683
|
-
# self.parent().po.all['all_specimens_have_same_direction'] = self.all_specimens_have_same_direction.isChecked()
|
|
684
|
-
|
|
685
699
|
def do_distant_shape_int_changed(self):
|
|
686
|
-
"""
|
|
700
|
+
"""
|
|
701
|
+
Toggles the visibility of widgets based the use of an algorithm allowing to connect distant shapes
|
|
702
|
+
during segmentation.
|
|
703
|
+
"""
|
|
687
704
|
do_distant_shape_int = self.connect_distant_shape_during_segmentation.isChecked()
|
|
688
705
|
self.detection_range_factor.setVisible(do_distant_shape_int)
|
|
689
706
|
if do_distant_shape_int:
|
|
@@ -701,7 +718,9 @@ class AdvancedParameters(WindowType):
|
|
|
701
718
|
self.min_size_for_connection_label.setVisible(do_use_min_size)
|
|
702
719
|
|
|
703
720
|
def use_max_size_changed(self):
|
|
704
|
-
"""
|
|
721
|
+
"""
|
|
722
|
+
Toggles the visibility of max size input fields based on checkbox state.
|
|
723
|
+
"""
|
|
705
724
|
do_use_max_size = self.use_max_size.isChecked()
|
|
706
725
|
self.max_size_for_connection.setVisible(do_use_max_size)
|
|
707
726
|
self.max_size_for_connection_label.setVisible(do_use_max_size)
|
|
@@ -709,7 +728,9 @@ class AdvancedParameters(WindowType):
|
|
|
709
728
|
self.max_size_for_connection.setValue(300)
|
|
710
729
|
|
|
711
730
|
def use_min_size_changed(self):
|
|
712
|
-
"""
|
|
731
|
+
"""
|
|
732
|
+
Updates the visibility and value of UI elements based on whether a checkbox is checked.
|
|
733
|
+
"""
|
|
713
734
|
do_use_min_size = self.use_min_size.isChecked()
|
|
714
735
|
self.min_size_for_connection.setVisible(do_use_min_size)
|
|
715
736
|
self.min_size_for_connection_label.setVisible(do_use_min_size)
|
|
@@ -717,50 +738,26 @@ class AdvancedParameters(WindowType):
|
|
|
717
738
|
self.min_size_for_connection.setValue(30)
|
|
718
739
|
|
|
719
740
|
def generate_csc_editing(self):
|
|
720
|
-
|
|
741
|
+
"""
|
|
742
|
+
Generate CSC Editing Layout
|
|
743
|
+
|
|
744
|
+
Creates and configures the layout for Color Space Combination (CSC) editing in the video analysis window,
|
|
745
|
+
initializing widgets and connecting signals to slots for dynamic UI handling.
|
|
746
|
+
"""
|
|
721
747
|
self.edit_widget = QtWidgets.QWidget()
|
|
722
|
-
# self.edit_widget.setVisible(False)
|
|
723
|
-
# self.edit_widget.setStyleSheet(boxstylesheet)
|
|
724
748
|
self.edit_layout = QtWidgets.QVBoxLayout()
|
|
725
|
-
|
|
726
|
-
# self.csc_scroll_table = QtWidgets.QScrollArea() # QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
|
|
727
|
-
# # self.csc_scroll_table.setVisible(False)
|
|
728
|
-
# # self.csc_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
|
729
|
-
# self.csc_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
|
730
|
-
# self.csc_scroll_table.setMinimumHeight(150)#self.parent().im_max_height - 100
|
|
731
|
-
# # self.csc_scroll_table.setMinimumWidth(300)
|
|
732
|
-
# self.csc_scroll_table.setFrameShape(QtWidgets.QFrame.NoFrame)
|
|
733
|
-
# self.csc_scroll_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
734
|
-
# self.csc_scroll_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
735
749
|
self.csc_table_widget = QtWidgets.QWidget()
|
|
736
750
|
self.csc_table_layout = QtWidgets.QVBoxLayout()
|
|
737
751
|
|
|
738
752
|
# 2) Titles
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
# self.edit_labels_layout = QtWidgets.QHBoxLayout()
|
|
742
|
-
# self.space_label = FixedText('Space', align='c',
|
|
743
|
-
# tip="Color spaces are transformations of the original BGR (Blue Green Red) image\nInstead of defining an image by 3 colors,\n they transform it into 3 different visual properties\n - hsv: hue (color), saturation, value (lightness)\n - hls: hue (color), lightness, saturation\n - lab: Lightness, Red/Green, Blue/Yellow\n - luv and yuv: l and y are Lightness, u and v are related to colors\n",
|
|
744
|
-
# night_mode=self.parent().po.all['night_mode'])
|
|
745
|
-
# self.c1 = FixedText(' C1', align='c', tip="Increase if it increase cell detection", night_mode=self.parent().po.all['night_mode'])
|
|
746
|
-
# self.c2 = FixedText(' C2', align='c', tip="Increase if it increase cell detection", night_mode=self.parent().po.all['night_mode'])
|
|
747
|
-
# self.c3 = FixedText(' C3', align='c', tip="Increase if it increase cell detection", night_mode=self.parent().po.all['night_mode'])
|
|
748
|
-
#
|
|
749
|
-
# self.edit_labels_layout.addWidget(self.space_label)
|
|
750
|
-
# self.edit_labels_layout.addWidget(self.c1)
|
|
751
|
-
# self.edit_labels_layout.addWidget(self.c2)
|
|
752
|
-
# self.edit_labels_layout.addWidget(self.c3)
|
|
753
|
-
# self.edit_labels_layout.addItem(self.horizontal_space)
|
|
754
|
-
# self.edit_labels_widget.setLayout(self.edit_labels_layout)
|
|
755
|
-
# # self.edit_layout.addWidget(self.edit_labels_widget)
|
|
756
|
-
# self.csc_table_layout.addWidget(self.edit_labels_widget)
|
|
757
|
-
self.video_csc_label = FixedText('Color space combination for video analysis:', tip="",
|
|
753
|
+
self.video_csc_label = FixedText(AP["Csc_for_video_analysis"]["label"] + ':',
|
|
754
|
+
tip=AP["Csc_for_video_analysis"]["tips"],
|
|
758
755
|
night_mode=self.parent().po.all['night_mode'])
|
|
759
756
|
self.video_csc_label.setFixedHeight(30)
|
|
760
757
|
self.csc_table_layout.addWidget(self.video_csc_label)
|
|
761
|
-
|
|
762
758
|
self.both_csc_widget = QtWidgets.QWidget()
|
|
763
759
|
self.both_csc_layout = QtWidgets.QHBoxLayout()
|
|
760
|
+
|
|
764
761
|
# 3) First CSC
|
|
765
762
|
self.first_csc_widget = QtWidgets.QWidget()
|
|
766
763
|
self.first_csc_layout = QtWidgets.QGridLayout()
|
|
@@ -774,17 +771,13 @@ class AdvancedParameters(WindowType):
|
|
|
774
771
|
self.logical_operator_between_combination_result.setCurrentText(self.parent().po.vars['convert_for_motion']['logical'])
|
|
775
772
|
self.logical_operator_between_combination_result.currentTextChanged.connect(self.logical_op_changed)
|
|
776
773
|
self.logical_operator_between_combination_result.setFixedWidth(100)
|
|
777
|
-
|
|
778
|
-
self.logical_operator_label = FixedText("Logical operator", halign='c', tip="Between selected color space combinations",
|
|
774
|
+
self.logical_operator_label = FixedText(IAW["Logical_operator"]["label"], halign='c', tip=IAW["Logical_operator"]["tips"],
|
|
779
775
|
night_mode=self.parent().po.all['night_mode'])
|
|
780
|
-
|
|
781
776
|
self.row21 = self.one_csc_editing()
|
|
782
777
|
self.row21[4].clicked.connect(self.display_row22)
|
|
783
778
|
self.row22 = self.one_csc_editing()
|
|
784
779
|
self.row22[4].clicked.connect(self.display_row23)
|
|
785
780
|
self.row23 = self.one_csc_editing()
|
|
786
|
-
|
|
787
|
-
|
|
788
781
|
for i in range(5):
|
|
789
782
|
self.first_csc_layout.addWidget(self.row1[i], 0, i, 1, 1)
|
|
790
783
|
self.first_csc_layout.addWidget(self.row2[i], 1, i, 1, 1)
|
|
@@ -796,9 +789,6 @@ class AdvancedParameters(WindowType):
|
|
|
796
789
|
self.first_csc_layout.addItem(self.horizontal_space, 0, 5, 3, 1)
|
|
797
790
|
self.first_csc_widget.setLayout(self.first_csc_layout)
|
|
798
791
|
self.both_csc_layout.addWidget(self.first_csc_widget)
|
|
799
|
-
# self.csc_table_layout.addWidget(self.first_csc_widget)
|
|
800
|
-
# self.edit_layout.addWidget(self.first_csc_widget)
|
|
801
|
-
|
|
802
792
|
|
|
803
793
|
# 5) Second CSC
|
|
804
794
|
self.second_csc_widget = QtWidgets.QWidget()
|
|
@@ -817,8 +807,6 @@ class AdvancedParameters(WindowType):
|
|
|
817
807
|
self.both_csc_layout.addWidget(self.second_csc_widget)
|
|
818
808
|
self.both_csc_widget.setLayout(self.both_csc_layout)
|
|
819
809
|
self.csc_table_layout.addWidget(self.both_csc_widget)
|
|
820
|
-
# self.csc_table_layout.addWidget(self.second_csc_widget)
|
|
821
|
-
|
|
822
810
|
|
|
823
811
|
# 4) logical_operator
|
|
824
812
|
self.logical_op_widget = QtWidgets.QWidget()
|
|
@@ -832,26 +820,26 @@ class AdvancedParameters(WindowType):
|
|
|
832
820
|
self.logical_op_widget.setLayout(self.logical_op_layout)
|
|
833
821
|
self.logical_op_widget.setFixedHeight(50)
|
|
834
822
|
self.csc_table_layout.addWidget(self.logical_op_widget)
|
|
835
|
-
# self.edit_layout.addWidget(self.logical_op_widget)
|
|
836
823
|
|
|
837
824
|
# 6) Open the more_than_2_colors row layout
|
|
838
825
|
self.more_than_2_colors_widget = QtWidgets.QWidget()
|
|
839
826
|
self.more_than_2_colors_layout = QtWidgets.QHBoxLayout()
|
|
840
827
|
self.more_than_two_colors = Checkbox(self.parent().po.all["more_than_two_colors"])
|
|
841
|
-
self.more_than_two_colors.setStyleSheet("
|
|
828
|
+
self.more_than_two_colors.setStyleSheet("QCheckBox::indicator {width: 12px;height: 12px;background-color: transparent;"
|
|
829
|
+
"border-radius: 5px;border-style: solid;border-width: 1px;"
|
|
830
|
+
"border-color: rgb(100,100,100);}"
|
|
831
|
+
"QCheckBox::indicator:checked {background-color: rgb(70,130,180);}"
|
|
832
|
+
"QCheckBox:checked, QCheckBox::indicator:checked {border-color: black black white white;}"
|
|
833
|
+
"QCheckBox:checked {background-color: transparent;}"
|
|
834
|
+
"QCheckBox:margin-left {0%}"
|
|
835
|
+
"QCheckBox:margin-right {-10%}")
|
|
842
836
|
self.more_than_two_colors.stateChanged.connect(self.display_more_than_two_colors_option)
|
|
843
837
|
|
|
844
|
-
self.more_than_two_colors_label = FixedText("
|
|
845
|
-
tip="
|
|
838
|
+
self.more_than_two_colors_label = FixedText(IAW["Kmeans"]["label"],
|
|
839
|
+
tip=IAW["Kmeans"]["tips"], night_mode=self.parent().po.all['night_mode'])
|
|
846
840
|
self.more_than_two_colors_label.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
847
|
-
# self.more_than_two_colors_label.setFixedWidth(300)
|
|
848
841
|
self.more_than_two_colors_label.setAlignment(QtCore.Qt.AlignLeft)
|
|
849
842
|
self.distinct_colors_number = Spinbox(min=2, max=5, val=self.parent().po.vars["color_number"], night_mode=self.parent().po.all['night_mode'])
|
|
850
|
-
# self.distinct_colors_number.valueChanged.connect(self.distinct_colors_number_changed)
|
|
851
|
-
# self.display_more_than_two_colors_option()
|
|
852
|
-
# self.more_than_two_colors.setVisible(False)
|
|
853
|
-
# self.more_than_two_colors_label.setVisible(False)
|
|
854
|
-
# self.distinct_colors_number.setVisible(False)
|
|
855
843
|
self.more_than_2_colors_layout.addWidget(self.more_than_two_colors)
|
|
856
844
|
self.more_than_2_colors_layout.addWidget(self.more_than_two_colors_label)
|
|
857
845
|
self.more_than_2_colors_layout.addWidget(self.distinct_colors_number)
|
|
@@ -863,20 +851,24 @@ class AdvancedParameters(WindowType):
|
|
|
863
851
|
self.csc_table_widget.setLayout(self.csc_table_layout)
|
|
864
852
|
|
|
865
853
|
self.edit_layout.addWidget(self.csc_table_widget)
|
|
866
|
-
# self.csc_scroll_table.setWidget(self.csc_table_widget)
|
|
867
|
-
# self.csc_scroll_table.setWidgetResizable(True)
|
|
868
|
-
# self.edit_layout.addWidget(self.csc_scroll_table)
|
|
869
|
-
|
|
870
|
-
# self.more_than_2_colors_layout.addWidget(self.more_than_two_colors)
|
|
871
|
-
# self.more_than_2_colors_layout.addWidget(self.more_than_two_colors_label)
|
|
872
|
-
# self.more_than_2_colors_layout.addWidget(self.distinct_colors_number)
|
|
873
|
-
# self.more_than_2_colors_layout.addItem(self.horizontal_space)
|
|
874
|
-
# self.more_than_2_colors_widget.setLayout(self.more_than_2_colors_layout)
|
|
875
|
-
# self.edit_layout.addWidget(self.more_than_2_colors_widget)
|
|
876
854
|
|
|
877
855
|
self.edit_widget.setLayout(self.edit_layout)
|
|
878
856
|
|
|
879
857
|
def one_csc_editing(self):
|
|
858
|
+
"""
|
|
859
|
+
Creates a list of widgets for color space editing.
|
|
860
|
+
|
|
861
|
+
Returns
|
|
862
|
+
-------
|
|
863
|
+
widget_list : List[QtWidgets.QWidget]
|
|
864
|
+
A list containing a Combobox, three Spinboxes, and a PButton.
|
|
865
|
+
|
|
866
|
+
Notes
|
|
867
|
+
-----
|
|
868
|
+
The Combobox widget allows selection from predefined color spaces,
|
|
869
|
+
the Spinboxes are for editing numerical values, and the PButton is
|
|
870
|
+
for adding new entries.
|
|
871
|
+
"""
|
|
880
872
|
widget_list = []
|
|
881
873
|
widget_list.insert(0, Combobox(["None", "bgr", "hsv", "hls", "lab", "luv", "yuv"],
|
|
882
874
|
night_mode=self.parent().po.all['night_mode']))
|
|
@@ -890,6 +882,9 @@ class AdvancedParameters(WindowType):
|
|
|
890
882
|
return widget_list
|
|
891
883
|
|
|
892
884
|
def logical_op_changed(self):
|
|
885
|
+
"""
|
|
886
|
+
Update the visibility and values of UI components based on the logical operator selection.
|
|
887
|
+
"""
|
|
893
888
|
# show = self.logical_operator_between_combination_result.currentText() != 'None'
|
|
894
889
|
if self.logical_operator_between_combination_result.currentText() == 'None':
|
|
895
890
|
self.row21[0].setVisible(False)
|
|
@@ -919,71 +914,100 @@ class AdvancedParameters(WindowType):
|
|
|
919
914
|
self.row21[i1 + 1].setVisible(True)
|
|
920
915
|
|
|
921
916
|
def display_logical_operator(self):
|
|
917
|
+
"""
|
|
918
|
+
Display logical operator components in the user interface.
|
|
919
|
+
"""
|
|
922
920
|
self.logical_operator_between_combination_result.setVisible(True)
|
|
923
921
|
self.logical_operator_label.setVisible(True)
|
|
924
922
|
|
|
925
923
|
def display_row2(self):
|
|
924
|
+
"""
|
|
925
|
+
Display or hide the second row of the csc editing widgets.
|
|
926
|
+
"""
|
|
926
927
|
self.row1[4].setVisible(False)
|
|
927
928
|
for i in range(5):
|
|
928
929
|
self.row2[i].setVisible(True)
|
|
929
930
|
self.display_logical_operator()
|
|
930
931
|
|
|
931
932
|
def display_row3(self):
|
|
933
|
+
"""
|
|
934
|
+
Display or hide the third row of the csc editing widgets.
|
|
935
|
+
"""
|
|
932
936
|
self.row2[4].setVisible(False)
|
|
933
937
|
for i in range(4):
|
|
934
938
|
self.row3[i].setVisible(True)
|
|
935
939
|
self.display_logical_operator()
|
|
936
940
|
|
|
937
941
|
def display_row22(self):
|
|
942
|
+
"""
|
|
943
|
+
Display or hide the second row (for the second image segmentation pipeline) of the csc editing widgets.
|
|
944
|
+
"""
|
|
938
945
|
self.row21[4].setVisible(False)
|
|
939
946
|
for i in range(5):
|
|
940
947
|
self.row22[i].setVisible(True)
|
|
941
948
|
self.display_logical_operator()
|
|
942
949
|
|
|
943
950
|
def display_row23(self):
|
|
951
|
+
"""
|
|
952
|
+
Display or hide the third row (for the second image segmentation pipeline) of the csc editing widgets.
|
|
953
|
+
"""
|
|
944
954
|
self.row22[4].setVisible(False)
|
|
945
955
|
for i in range(4):
|
|
946
956
|
self.row23[i].setVisible(True)
|
|
947
957
|
self.display_logical_operator()
|
|
948
958
|
|
|
949
959
|
def update_csc_editing_display(self):
|
|
960
|
+
"""
|
|
961
|
+
Update the color space conversion (CSC) editing display.
|
|
962
|
+
|
|
963
|
+
This method updates the visibility and values of UI elements related to color
|
|
964
|
+
space conversions based on the current state of `self.csc_dict`. It handles
|
|
965
|
+
the display logic for different color spaces and their combinations, ensuring
|
|
966
|
+
that the UI reflects the current configuration accurately.
|
|
967
|
+
"""
|
|
950
968
|
c_space_order = ["None", "bgr", "hsv", "hls", "lab", "luv", "yuv"]
|
|
951
969
|
remaining_c_spaces = []
|
|
952
970
|
row_number1 = 0
|
|
953
971
|
row_number2 = 0
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
row_to_change = self.row23
|
|
972
|
+
if "PCA" in self.parent().po.vars['convert_for_motion'].keys():
|
|
973
|
+
self.row1[0].setCurrentIndex(0)
|
|
974
|
+
self.row1[0].setVisible(True)
|
|
975
|
+
for i in range(1, 4):
|
|
976
|
+
self.row1[i].setVisible(False)
|
|
977
|
+
else:
|
|
978
|
+
for i, (k, v) in enumerate(self.parent().po.vars['convert_for_motion'].items()):
|
|
979
|
+
if k != "logical":
|
|
980
|
+
if k[-1] != "2":
|
|
981
|
+
if row_number1 == 0:
|
|
982
|
+
row_to_change = self.row1
|
|
983
|
+
elif row_number1 == 1:
|
|
984
|
+
row_to_change = self.row2
|
|
985
|
+
elif row_number1 == 2:
|
|
986
|
+
row_to_change = self.row3
|
|
987
|
+
else:
|
|
988
|
+
remaining_c_spaces.append(k + " " + str(v))
|
|
989
|
+
row_number1 += 1
|
|
990
|
+
current_row_number = row_number1
|
|
974
991
|
else:
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
992
|
+
if row_number2 == 0:
|
|
993
|
+
row_to_change = self.row21
|
|
994
|
+
elif row_number2 == 1:
|
|
995
|
+
row_to_change = self.row22
|
|
996
|
+
elif row_number2 == 2:
|
|
997
|
+
row_to_change = self.row23
|
|
998
|
+
else:
|
|
999
|
+
remaining_c_spaces.append(k + " " + str(v))
|
|
1000
|
+
row_number2 += 1
|
|
1001
|
+
current_row_number = row_number2
|
|
1002
|
+
k = k[:-1]
|
|
1003
|
+
if current_row_number <= 3:
|
|
1004
|
+
row_to_change[0].setCurrentIndex(np.nonzero(np.isin(c_space_order, k))[0][0])
|
|
1005
|
+
row_to_change[0].setVisible(True)
|
|
1006
|
+
for i1, i2 in zip([1, 2, 3], [0, 1, 2]):
|
|
1007
|
+
row_to_change[i1].setValue(v[i2])
|
|
1008
|
+
row_to_change[i1].setVisible(True)
|
|
1009
|
+
if current_row_number < 3:
|
|
1010
|
+
row_to_change[i1 + 1].setVisible(True)
|
|
987
1011
|
|
|
988
1012
|
# If not all color space combinations are filled, put None and 0 in boxes
|
|
989
1013
|
if row_number1 < 3:
|
|
@@ -1037,6 +1061,9 @@ class AdvancedParameters(WindowType):
|
|
|
1037
1061
|
self.row22[i1 + 1].setVisible(False)
|
|
1038
1062
|
|
|
1039
1063
|
def save_user_defined_csc(self):
|
|
1064
|
+
"""
|
|
1065
|
+
Save user-defined combination of color spaces and channels.
|
|
1066
|
+
"""
|
|
1040
1067
|
self.parent().po.vars['convert_for_motion'] = {}
|
|
1041
1068
|
spaces = np.array((self.row1[0].currentText(), self.row2[0].currentText(), self.row3[0].currentText()))
|
|
1042
1069
|
channels = np.array(
|
|
@@ -1061,6 +1088,8 @@ class AdvancedParameters(WindowType):
|
|
|
1061
1088
|
if not np.all(spaces == "None"):
|
|
1062
1089
|
for i, space in enumerate(spaces):
|
|
1063
1090
|
if space != "None" and space != "None2":
|
|
1091
|
+
if np.any(channels[i, :] < 0.):
|
|
1092
|
+
channels[i, :] + channels[i, :].min()
|
|
1064
1093
|
self.parent().po.vars['convert_for_motion'][space] = channels[i, :]
|
|
1065
1094
|
if len(self.parent().po.vars['convert_for_motion']) == 1 or channels.sum() == 0:
|
|
1066
1095
|
self.csc_dict_is_empty = True
|
|
@@ -1074,6 +1103,12 @@ class AdvancedParameters(WindowType):
|
|
|
1074
1103
|
self.parent().videoanalysiswindow.select_option_label.setVisible(True)
|
|
1075
1104
|
|
|
1076
1105
|
def display_more_than_two_colors_option(self):
|
|
1106
|
+
"""
|
|
1107
|
+
Display the More Than Two Colors Options
|
|
1108
|
+
|
|
1109
|
+
This method manages the visibility and state of UI elements related to selecting
|
|
1110
|
+
more than two colors for displaying biological masks in advanced mode.
|
|
1111
|
+
"""
|
|
1077
1112
|
if self.more_than_two_colors.isChecked():
|
|
1078
1113
|
self.distinct_colors_number.setVisible(True)
|
|
1079
1114
|
self.more_than_two_colors_label.setText("How many distinct colors?")
|
|
@@ -1083,12 +1118,6 @@ class AdvancedParameters(WindowType):
|
|
|
1083
1118
|
self.distinct_colors_number.setVisible(False)
|
|
1084
1119
|
self.distinct_colors_number.setValue(2)
|
|
1085
1120
|
|
|
1086
|
-
|
|
1087
|
-
# self.parent().po.vars["color_number"] = 2
|
|
1088
|
-
|
|
1089
|
-
# def distinct_colors_number_changed(self):
|
|
1090
|
-
# self.parent().po.vars["color_number"] = int(self.distinct_colors_number.value())
|
|
1091
|
-
|
|
1092
1121
|
def night_mode_is_clicked(self):
|
|
1093
1122
|
""" Triggered when night_mode_cb check status changes"""
|
|
1094
1123
|
self.parent().po.all['night_mode'] = self.night_mode_cb.isChecked()
|
|
@@ -1096,6 +1125,16 @@ class AdvancedParameters(WindowType):
|
|
|
1096
1125
|
self.message.setStyleSheet("color: rgb(230, 145, 18)")
|
|
1097
1126
|
|
|
1098
1127
|
def reset_all_settings_is_clicked(self):
|
|
1128
|
+
"""
|
|
1129
|
+
Reset All Settings on Click
|
|
1130
|
+
|
|
1131
|
+
Resets the application settings to their default state by removing specific pickle files and saving new default dictionaries.
|
|
1132
|
+
|
|
1133
|
+
Notes
|
|
1134
|
+
-----
|
|
1135
|
+
- This function removes specific pickle files to reset settings.
|
|
1136
|
+
- The function changes the current working directory temporarily.
|
|
1137
|
+
"""
|
|
1099
1138
|
if os.path.isfile('Data to run Cellects quickly.pkl'):
|
|
1100
1139
|
os.remove('Data to run Cellects quickly.pkl')
|
|
1101
1140
|
if os.path.isfile('PickleRick.pkl'):
|
|
@@ -1116,6 +1155,13 @@ class AdvancedParameters(WindowType):
|
|
|
1116
1155
|
self.message.setStyleSheet("color: rgb(230, 145, 18)")
|
|
1117
1156
|
|
|
1118
1157
|
def cancel_is_clicked(self):
|
|
1158
|
+
"""
|
|
1159
|
+
Instead of saving the widgets values to the saved states, use the saved states to fill in the widgets.
|
|
1160
|
+
|
|
1161
|
+
This function updates the state of several checkboxes based on saved variables
|
|
1162
|
+
and descriptors. It also changes the active widget to either the first or third
|
|
1163
|
+
widget depending on a condition.
|
|
1164
|
+
"""
|
|
1119
1165
|
self.automatically_crop.setChecked(self.parent().po.all['automatically_crop'])
|
|
1120
1166
|
self.subtract_background.setChecked(self.parent().po.vars['subtract_background'])
|
|
1121
1167
|
self.keep_cell_and_back_for_all_folders.setChecked(self.parent().po.all['keep_cell_and_back_for_all_folders'])
|
|
@@ -1132,8 +1178,6 @@ class AdvancedParameters(WindowType):
|
|
|
1132
1178
|
self.oscillation_period.setValue(self.parent().po.vars['expected_oscillation_period'])
|
|
1133
1179
|
self.minimal_oscillating_cluster_size.setValue(self.parent().po.vars['minimal_oscillating_cluster_size'])
|
|
1134
1180
|
|
|
1135
|
-
self.network_detection_threshold.setValue(self.parent().po.vars['network_detection_threshold'])
|
|
1136
|
-
|
|
1137
1181
|
self.do_multiprocessing.setChecked(self.parent().po.all['do_multiprocessing'])
|
|
1138
1182
|
self.max_core_nb.setValue(self.parent().po.all['cores'])
|
|
1139
1183
|
self.min_memory_left.setValue(self.parent().po.vars['min_ram_free'])
|
|
@@ -1168,11 +1212,20 @@ class AdvancedParameters(WindowType):
|
|
|
1168
1212
|
self.parent().change_widget(3) # ImageAnalysisWindow ThirdWidget
|
|
1169
1213
|
|
|
1170
1214
|
def ok_is_clicked(self):
|
|
1171
|
-
"""
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1215
|
+
"""
|
|
1216
|
+
Updates the parent object's processing options with the current state of various UI elements.
|
|
1217
|
+
|
|
1218
|
+
Summary
|
|
1219
|
+
-------
|
|
1220
|
+
Saves the current state of UI components to the parent object's processing options dictionary.
|
|
1221
|
+
|
|
1222
|
+
Extended Description
|
|
1223
|
+
--------------------
|
|
1224
|
+
This method iterates through various UI components such as checkboxes, sliders,
|
|
1225
|
+
and dropdowns to save their current state into the parent object's processing
|
|
1226
|
+
options variables. This allows the software to retain user preferences across
|
|
1227
|
+
sessions and ensures that all settings are correctly applied before processing.
|
|
1228
|
+
"""
|
|
1176
1229
|
self.parent().po.all['automatically_crop'] = self.automatically_crop.isChecked()
|
|
1177
1230
|
self.parent().po.vars['subtract_background'] = self.subtract_background.isChecked()
|
|
1178
1231
|
self.parent().po.all['keep_cell_and_back_for_all_folders'] = self.keep_cell_and_back_for_all_folders.isChecked()
|
|
@@ -1181,16 +1234,32 @@ class AdvancedParameters(WindowType):
|
|
|
1181
1234
|
self.parent().po.vars['periphery_width'] = int(self.periphery_width.value())
|
|
1182
1235
|
self.parent().po.vars['max_periphery_growth'] = int(self.max_periphery_growth.value())
|
|
1183
1236
|
|
|
1184
|
-
# if self.parent().po.vars['origin_state'] == "invisible":
|
|
1185
1237
|
self.parent().po.all['first_move_threshold_in_mm²'] = self.first_move_threshold.value()
|
|
1186
1238
|
self.parent().po.vars['output_in_mm'] = self.pixels_to_mm.isChecked()
|
|
1187
1239
|
self.parent().po.all['automatic_size_thresholding'] = self.do_automatic_size_thresholding.isChecked()
|
|
1188
1240
|
self.parent().po.vars['appearance_detection_method'] = self.appearing_selection.currentText()
|
|
1241
|
+
|
|
1242
|
+
self.parent().po.all['auto_mesh_step_length'] = self.mesh_step_length_cb.isChecked()
|
|
1243
|
+
if self.parent().po.all['auto_mesh_step_length']:
|
|
1244
|
+
self.parent().po.vars['rolling_window_segmentation']['step'] = None
|
|
1245
|
+
else:
|
|
1246
|
+
self.parent().po.vars['rolling_window_segmentation']['step'] = int(self.mesh_step_length.value())
|
|
1247
|
+
|
|
1248
|
+
self.parent().po.all['auto_mesh_side_length'] = self.mesh_side_length_cb.isChecked()
|
|
1249
|
+
if self.parent().po.all['auto_mesh_side_length']:
|
|
1250
|
+
self.parent().po.vars['rolling_window_segmentation']['side_len'] = None
|
|
1251
|
+
else:
|
|
1252
|
+
self.parent().po.vars['rolling_window_segmentation']['side_len'] = int(self.mesh_side_length.value())
|
|
1253
|
+
|
|
1254
|
+
self.parent().po.all['auto_mesh_min_int_var'] = self.mesh_min_int_var_cb.isChecked()
|
|
1255
|
+
if self.parent().po.all['auto_mesh_min_int_var']:
|
|
1256
|
+
self.parent().po.vars['rolling_window_segmentation']['min_int_var'] = None
|
|
1257
|
+
else:
|
|
1258
|
+
self.parent().po.vars['rolling_window_segmentation']['min_int_var'] = int(self.mesh_min_int_var.value())
|
|
1259
|
+
|
|
1189
1260
|
self.parent().po.vars['expected_oscillation_period'] = self.oscillation_period.value()
|
|
1190
1261
|
self.parent().po.vars['minimal_oscillating_cluster_size'] = int(self.minimal_oscillating_cluster_size.value())
|
|
1191
1262
|
|
|
1192
|
-
self.parent().po.vars['network_detection_threshold'] = int(np.round(self.network_detection_threshold.value()))
|
|
1193
|
-
|
|
1194
1263
|
self.parent().po.all['do_multiprocessing'] = self.do_multiprocessing.isChecked()
|
|
1195
1264
|
self.parent().po.all['cores'] = np.uint8(self.max_core_nb.value())
|
|
1196
1265
|
self.parent().po.vars['min_ram_free'] = self.min_memory_left.value()
|
|
@@ -1221,7 +1290,6 @@ class AdvancedParameters(WindowType):
|
|
|
1221
1290
|
|
|
1222
1291
|
previous_csc = deepcopy(self.parent().po.vars['convert_for_motion'])
|
|
1223
1292
|
self.save_user_defined_csc()
|
|
1224
|
-
print(self.parent().po.vars['convert_for_motion'])
|
|
1225
1293
|
if self.parent().po.first_exp_ready_to_run:
|
|
1226
1294
|
are_dicts_equal: bool = True
|
|
1227
1295
|
for key in previous_csc.keys():
|
|
@@ -1244,15 +1312,7 @@ class AdvancedParameters(WindowType):
|
|
|
1244
1312
|
self.parent().change_widget(3) # ImageAnalysisWindow ThirdWidget
|
|
1245
1313
|
|
|
1246
1314
|
def closeEvent(self, event):
|
|
1315
|
+
"""
|
|
1316
|
+
Handle the close event for a QWidget.
|
|
1317
|
+
"""
|
|
1247
1318
|
event.accept
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
# if __name__ == "__main__":
|
|
1251
|
-
# from cellects.gui.cellects import CellectsMainWidget
|
|
1252
|
-
# import sys
|
|
1253
|
-
# app = QtWidgets.QApplication([])
|
|
1254
|
-
# parent = CellectsMainWidget()
|
|
1255
|
-
# session = AdvancedParameters(parent, False)
|
|
1256
|
-
# parent.insertWidget(0, session)
|
|
1257
|
-
# parent.show()
|
|
1258
|
-
# sys.exit(app.exec())
|