cellects 0.1.0.dev1__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/__init__.py +0 -0
- cellects/__main__.py +49 -0
- cellects/config/__init__.py +0 -0
- cellects/config/all_vars_dict.py +154 -0
- cellects/core/__init__.py +0 -0
- cellects/core/cellects_paths.py +30 -0
- cellects/core/cellects_threads.py +1464 -0
- cellects/core/motion_analysis.py +1931 -0
- cellects/core/one_image_analysis.py +1065 -0
- cellects/core/one_video_per_blob.py +679 -0
- cellects/core/program_organizer.py +1347 -0
- cellects/core/script_based_run.py +154 -0
- cellects/gui/__init__.py +0 -0
- cellects/gui/advanced_parameters.py +1258 -0
- cellects/gui/cellects.py +189 -0
- cellects/gui/custom_widgets.py +789 -0
- cellects/gui/first_window.py +449 -0
- cellects/gui/if_several_folders_window.py +239 -0
- cellects/gui/image_analysis_window.py +1909 -0
- cellects/gui/required_output.py +232 -0
- cellects/gui/video_analysis_window.py +656 -0
- cellects/icons/__init__.py +0 -0
- cellects/icons/cellects_icon.icns +0 -0
- cellects/icons/cellects_icon.ico +0 -0
- cellects/image_analysis/__init__.py +0 -0
- cellects/image_analysis/cell_leaving_detection.py +54 -0
- cellects/image_analysis/cluster_flux_study.py +102 -0
- cellects/image_analysis/extract_exif.py +61 -0
- cellects/image_analysis/fractal_analysis.py +184 -0
- cellects/image_analysis/fractal_functions.py +108 -0
- cellects/image_analysis/image_segmentation.py +272 -0
- cellects/image_analysis/morphological_operations.py +867 -0
- cellects/image_analysis/network_functions.py +1244 -0
- cellects/image_analysis/one_image_analysis_threads.py +289 -0
- cellects/image_analysis/progressively_add_distant_shapes.py +246 -0
- cellects/image_analysis/shape_descriptors.py +981 -0
- cellects/utils/__init__.py +0 -0
- cellects/utils/formulas.py +881 -0
- cellects/utils/load_display_save.py +1016 -0
- cellects/utils/utilitarian.py +516 -0
- cellects-0.1.0.dev1.dist-info/LICENSE.odt +0 -0
- cellects-0.1.0.dev1.dist-info/METADATA +131 -0
- cellects-0.1.0.dev1.dist-info/RECORD +46 -0
- cellects-0.1.0.dev1.dist-info/WHEEL +5 -0
- cellects-0.1.0.dev1.dist-info/entry_points.txt +2 -0
- cellects-0.1.0.dev1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1258 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""This module creates the Advanced Parameters window of the user interface of Cellects
|
|
3
|
+
This windows contains most parameters
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
from copy import deepcopy
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from PySide6 import QtWidgets, QtCore
|
|
13
|
+
import numpy as np
|
|
14
|
+
from cellects.config.all_vars_dict import DefaultDicts
|
|
15
|
+
from cellects.core.cellects_paths import CELLECTS_DIR, CONFIG_DIR
|
|
16
|
+
from cellects.gui.custom_widgets import (
|
|
17
|
+
WindowType, PButton, Spinbox, Combobox, Checkbox, FixedText)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AdvancedParameters(WindowType):
|
|
21
|
+
"""
|
|
22
|
+
This class creates the Advanced Parameters window.
|
|
23
|
+
In the app, it is accessible from the first and the Video tracking window. It allows the user to fill in
|
|
24
|
+
some parameters stored in the directory po.all (in RAM) and in all_vars.pkl (in ROM).
|
|
25
|
+
Clicking "Ok" save the directory in RAM and in ROM.
|
|
26
|
+
"""
|
|
27
|
+
def __init__(self, parent, night_mode):
|
|
28
|
+
super().__init__(parent, night_mode)
|
|
29
|
+
|
|
30
|
+
logging.info("Initialize AdvancedParameters window")
|
|
31
|
+
self.setParent(parent)
|
|
32
|
+
try:
|
|
33
|
+
self.true_init()
|
|
34
|
+
except KeyError:
|
|
35
|
+
default_dicts = DefaultDicts()
|
|
36
|
+
self.parent().po.all = default_dicts.all
|
|
37
|
+
self.parent().po.vars = default_dicts.vars
|
|
38
|
+
self.true_init()
|
|
39
|
+
|
|
40
|
+
def true_init(self):
|
|
41
|
+
self.layout = QtWidgets.QVBoxLayout()
|
|
42
|
+
|
|
43
|
+
self.left_scroll_table = QtWidgets.QScrollArea() # QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
|
|
44
|
+
self.left_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
|
45
|
+
self.left_scroll_table.setMinimumHeight(150)#self.parent().im_max_height - 100
|
|
46
|
+
self.left_scroll_table.setFrameShape(QtWidgets.QFrame.NoFrame)
|
|
47
|
+
self.left_scroll_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
48
|
+
self.left_scroll_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
49
|
+
|
|
50
|
+
self.left_col_layout = QtWidgets.QVBoxLayout()
|
|
51
|
+
self.right_col_layout = QtWidgets.QVBoxLayout()
|
|
52
|
+
self.left_col_widget = QtWidgets.QWidget()
|
|
53
|
+
self.right_col_widget = QtWidgets.QWidget()
|
|
54
|
+
# curr_row_1st_col = 0
|
|
55
|
+
ncol = 11
|
|
56
|
+
# Create the main Title
|
|
57
|
+
self.title = FixedText('Advanced parameters', police=30, night_mode=self.parent().po.all['night_mode'])
|
|
58
|
+
self.title.setAlignment(QtCore.Qt.AlignHCenter)
|
|
59
|
+
# Create the main layout
|
|
60
|
+
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
|
+
# Create the stylesheet for the boxes allowing to categorize advanced parameters.
|
|
68
|
+
boxstylesheet = \
|
|
69
|
+
".QWidget {\n" \
|
|
70
|
+
+ "border: 1px solid black;\n" \
|
|
71
|
+
+ "border-radius: 20px;\n" \
|
|
72
|
+
+ "}"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# I/ First box: General parameters
|
|
76
|
+
# I/A/ Title
|
|
77
|
+
self.general_param_box_label = FixedText('General parameters:', tip="",
|
|
78
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
79
|
+
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
|
+
# I/B/ Create the box
|
|
83
|
+
self.general_param_box_layout = QtWidgets.QGridLayout()
|
|
84
|
+
self.general_param_box_widget = QtWidgets.QWidget()
|
|
85
|
+
self.general_param_box_widget.setStyleSheet(boxstylesheet)
|
|
86
|
+
# I/C/ Create widgets
|
|
87
|
+
self.automatically_crop = Checkbox(self.parent().po.all['automatically_crop'])
|
|
88
|
+
self.automatically_crop_label = FixedText('Automatically crop images', tip="If more than one cell shape are (or may appear) in each arena", night_mode=self.parent().po.all['night_mode'])
|
|
89
|
+
|
|
90
|
+
self.subtract_background = Checkbox(self.parent().po.vars['subtract_background'])
|
|
91
|
+
self.subtract_background.stateChanged.connect(self.subtract_background_check)
|
|
92
|
+
self.subtract_background_label = FixedText('Subtract background', tip="Apply an algorithm allowing to remove a potential brightness gradient from images during analysis", night_mode=self.parent().po.all['night_mode'])
|
|
93
|
+
|
|
94
|
+
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('Keep Cell and Back drawings for all folders',
|
|
96
|
+
tip="During the first image analysis, if the user drew cell and back to help detection\n- Keep this information for all folders (if checked)\n- Only use this information for the current folder (if unchecked)",
|
|
97
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
98
|
+
|
|
99
|
+
self.correct_errors_around_initial = Checkbox(self.parent().po.vars['correct_errors_around_initial'])
|
|
100
|
+
self.correct_errors_around_initial_label = FixedText('Correct errors around initial shape',
|
|
101
|
+
tip="Apply an algorithm allowing to correct some failure around the initial shape\nThese errors are most likely due to color variations\n themselves due to substrate width differences crossed by light\naround initial cell lying on an opaque substrate",
|
|
102
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
103
|
+
|
|
104
|
+
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('Prevent fast growth near periphery',
|
|
106
|
+
tip="During video analysis, the borders of the arena may create wrong detection\n- Remove the detection of the specimen(s) that move too fast near periphery (if checked)\n- Do not change the detection (if unchecked)",
|
|
107
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
108
|
+
|
|
109
|
+
self.prevent_fast_growth_near_periphery.stateChanged.connect(self.prevent_fast_growth_near_periphery_check)
|
|
110
|
+
self.periphery_width = Spinbox(min=1, max=1000, val=self.parent().po.vars['periphery_width'],
|
|
111
|
+
decimals=0, night_mode=self.parent().po.all['night_mode'])
|
|
112
|
+
self.periphery_width_label = FixedText('Periphery width',
|
|
113
|
+
tip="The width, in pixels, of the arena s border designated as the peripheral region",
|
|
114
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
115
|
+
self.max_periphery_growth = Spinbox(min=1, max=1000000, val=self.parent().po.vars['max_periphery_growth'],
|
|
116
|
+
decimals=0, night_mode=self.parent().po.all['night_mode'])
|
|
117
|
+
self.max_periphery_growth_label = FixedText('Max periphery growth',
|
|
118
|
+
tip="The maximum detectable size (in pixels) of a shape in a single frame near the periphery of the arena.\nLarger shapes will be considered as noise.",
|
|
119
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
120
|
+
self.prevent_fast_growth_near_periphery_check()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# I/D/ Arrange widgets in the box
|
|
124
|
+
self.general_param_box_layout.addWidget(self.automatically_crop, 0, 0)
|
|
125
|
+
self.general_param_box_layout.addWidget(self.automatically_crop_label, 0, 1)
|
|
126
|
+
self.general_param_box_layout.addWidget(self.subtract_background, 1, 0)
|
|
127
|
+
self.general_param_box_layout.addWidget(self.subtract_background_label, 1, 1)
|
|
128
|
+
self.general_param_box_layout.addWidget(self.keep_cell_and_back_for_all_folders, 2, 0)
|
|
129
|
+
self.general_param_box_layout.addWidget(self.keep_cell_and_back_for_all_folders_label, 2, 1)
|
|
130
|
+
self.general_param_box_layout.addWidget(self.correct_errors_around_initial, 3, 0)
|
|
131
|
+
self.general_param_box_layout.addWidget(self.correct_errors_around_initial_label, 3, 1)
|
|
132
|
+
self.general_param_box_layout.addWidget(self.prevent_fast_growth_near_periphery, 4, 0)
|
|
133
|
+
self.general_param_box_layout.addWidget(self.prevent_fast_growth_near_periphery_label, 4, 1)
|
|
134
|
+
self.general_param_box_layout.addWidget(self.periphery_width, 5, 0)
|
|
135
|
+
self.general_param_box_layout.addWidget(self.periphery_width_label, 5, 1)
|
|
136
|
+
self.general_param_box_layout.addWidget(self.max_periphery_growth, 6, 0)
|
|
137
|
+
self.general_param_box_layout.addWidget(self.max_periphery_growth_label, 6, 1)
|
|
138
|
+
self.general_param_box_widget.setLayout(self.general_param_box_layout)
|
|
139
|
+
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
|
+
|
|
143
|
+
# II/ Second box: One cell/colony per arena
|
|
144
|
+
# II/A/ Title
|
|
145
|
+
self.one_per_arena_label = FixedText('One cell/colony per arena parameters:', tip="",
|
|
146
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
147
|
+
self.left_col_layout.addWidget(self.one_per_arena_label)
|
|
148
|
+
# II/B/ Create the box
|
|
149
|
+
self.one_per_arena_box_layout = QtWidgets.QGridLayout()
|
|
150
|
+
self.one_per_arena_box_widget = QtWidgets.QWidget()
|
|
151
|
+
self.one_per_arena_box_widget.setStyleSheet(boxstylesheet)
|
|
152
|
+
|
|
153
|
+
# II/C/ Create widgets
|
|
154
|
+
self.all_specimens_have_same_direction = Checkbox(self.parent().po.all['all_specimens_have_same_direction'])
|
|
155
|
+
# self.all_specimens_have_same_direction.stateChanged.connect(self.all_specimens_have_same_direction_changed)
|
|
156
|
+
self.all_specimens_have_same_direction_label = FixedText('All specimens have the same direction',
|
|
157
|
+
tip="This parameter only affects the slow algorithm of automatic arena detection.\nChecking it will improve the chances to correctly detect arenas when\n all cells move in the same direction",
|
|
158
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
connect_distant_shape = self.parent().po.all['connect_distant_shape_during_segmentation']
|
|
162
|
+
self.connect_distant_shape_during_segmentation = Checkbox(connect_distant_shape)
|
|
163
|
+
self.connect_distant_shape_during_segmentation.stateChanged.connect(self.do_distant_shape_int_changed)
|
|
164
|
+
self.connect_distant_shape_label = FixedText('Connect distant shapes',
|
|
165
|
+
tip="Allows a homemade algorithm allowing to\nprogressively (i.e. at the growth rate speed of neighboring pixels)\nconnect distant shapes to original shape(s)\nWarning: this option can drastically increase the duration of the analysis",
|
|
166
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
167
|
+
self.detection_range_factor = Spinbox(min=0, max=1000000,
|
|
168
|
+
val=self.parent().po.vars['detection_range_factor'],
|
|
169
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
170
|
+
self.detection_range_factor_label = FixedText('Detection range factor:',
|
|
171
|
+
tip="From 1 to 10, increase the allowed distance from original shape(s) to connect distant shapes",
|
|
172
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
173
|
+
|
|
174
|
+
# Connect distant shape algo:
|
|
175
|
+
do_use_max_size = self.parent().po.vars['max_size_for_connection'] is not None and connect_distant_shape
|
|
176
|
+
do_use_min_size = self.parent().po.vars['min_size_for_connection'] is not None and connect_distant_shape
|
|
177
|
+
self.use_max_size = Checkbox(do_use_max_size, night_mode=self.parent().po.all['night_mode'])
|
|
178
|
+
self.use_min_size = Checkbox(do_use_min_size, night_mode=self.parent().po.all['night_mode'])
|
|
179
|
+
self.use_max_size.stateChanged.connect(self.use_max_size_changed)
|
|
180
|
+
self.use_min_size.stateChanged.connect(self.use_min_size_changed)
|
|
181
|
+
|
|
182
|
+
self.use_max_size_label = FixedText('Use max size as a threshold',
|
|
183
|
+
tip="To decide whether distant shapes should get connected",
|
|
184
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
185
|
+
self.use_min_size_label = FixedText('Use min size as a threshold',
|
|
186
|
+
tip="To decide whether distant shapes should get connected",
|
|
187
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
188
|
+
self.max_size_for_connection_label = FixedText('Max (pixels):', night_mode=self.parent().po.all['night_mode'])
|
|
189
|
+
self.min_size_for_connection_label = FixedText('Min (pixels):', night_mode=self.parent().po.all['night_mode'])
|
|
190
|
+
if do_use_max_size:
|
|
191
|
+
self.max_size_for_connection = Spinbox(min=0, max=1000000,
|
|
192
|
+
val=self.parent().po.vars['max_size_for_connection'],
|
|
193
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
194
|
+
else:
|
|
195
|
+
self.max_size_for_connection = Spinbox(min=0, max=1000000, val=50,
|
|
196
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
197
|
+
if do_use_min_size:
|
|
198
|
+
self.min_size_for_connection = Spinbox(min=0, max=1000000,
|
|
199
|
+
val=self.parent().po.vars['min_size_for_connection'],
|
|
200
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
201
|
+
else:
|
|
202
|
+
self.min_size_for_connection = Spinbox(min=0, max=1000000, val=0,
|
|
203
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
204
|
+
# set things visible or invisible:
|
|
205
|
+
# self.detection_range_factor.setVisible(connect_distant_shape)
|
|
206
|
+
# self.detection_range_factor_label.setVisible(connect_distant_shape)
|
|
207
|
+
# self.use_max_size.setVisible(connect_distant_shape)
|
|
208
|
+
# self.use_min_size.setVisible(connect_distant_shape)
|
|
209
|
+
# self.use_max_size_label.setVisible(connect_distant_shape)
|
|
210
|
+
# self.use_min_size_label.setVisible(connect_distant_shape)
|
|
211
|
+
#
|
|
212
|
+
# self.max_size_for_connection.setVisible(do_use_max_size)
|
|
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%;")
|
|
218
|
+
self.min_size_for_connection_label.setAlignment(QtCore.Qt.AlignRight)
|
|
219
|
+
self.use_max_size.setStyleSheet("margin-left:100%; margin-right:0%;")
|
|
220
|
+
self.max_size_for_connection_label.setAlignment(QtCore.Qt.AlignRight)
|
|
221
|
+
|
|
222
|
+
# II/D/ Arrange widgets in the box
|
|
223
|
+
curr_box_row = 0
|
|
224
|
+
self.one_per_arena_box_layout.addWidget(self.connect_distant_shape_during_segmentation, curr_box_row, 0)
|
|
225
|
+
self.one_per_arena_box_layout.addWidget(self.connect_distant_shape_label, curr_box_row, 1)
|
|
226
|
+
curr_box_row += 1
|
|
227
|
+
self.one_per_arena_box_layout.addWidget(self.detection_range_factor, curr_box_row, 0)
|
|
228
|
+
self.one_per_arena_box_layout.addWidget(self.detection_range_factor_label, curr_box_row, 1)
|
|
229
|
+
curr_box_row += 1
|
|
230
|
+
self.one_per_arena_box_layout.addWidget(self.use_min_size, curr_box_row, 0)
|
|
231
|
+
self.one_per_arena_box_layout.addWidget(self.use_min_size_label, curr_box_row, 1)
|
|
232
|
+
curr_box_row += 1
|
|
233
|
+
self.one_per_arena_box_layout.addWidget(self.min_size_for_connection_label, curr_box_row, 0)
|
|
234
|
+
self.one_per_arena_box_layout.addWidget(self.min_size_for_connection, curr_box_row, 1)
|
|
235
|
+
curr_box_row += 1
|
|
236
|
+
self.one_per_arena_box_layout.addWidget(self.use_max_size, curr_box_row, 0)
|
|
237
|
+
self.one_per_arena_box_layout.addWidget(self.use_max_size_label, curr_box_row, 1)
|
|
238
|
+
curr_box_row += 1
|
|
239
|
+
self.one_per_arena_box_layout.addWidget(self.max_size_for_connection_label, curr_box_row, 0)
|
|
240
|
+
self.one_per_arena_box_layout.addWidget(self.max_size_for_connection, curr_box_row, 1)
|
|
241
|
+
curr_box_row += 1
|
|
242
|
+
self.one_per_arena_box_layout.addWidget(self.all_specimens_have_same_direction, curr_box_row, 0)
|
|
243
|
+
self.one_per_arena_box_layout.addWidget(self.all_specimens_have_same_direction_label, curr_box_row, 1)
|
|
244
|
+
curr_box_row += 1
|
|
245
|
+
|
|
246
|
+
self.one_per_arena_box_widget.setLayout(self.one_per_arena_box_layout)
|
|
247
|
+
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
|
+
|
|
251
|
+
# III/ Third box: Appearing cell/colony
|
|
252
|
+
# III/A/ Title
|
|
253
|
+
self.appearing_cell_label = FixedText('Appearing cell/colony parameters:', tip="",
|
|
254
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
255
|
+
|
|
256
|
+
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
|
+
# III/B/ Create the box
|
|
260
|
+
self.appearing_cell_box_layout = QtWidgets.QGridLayout()
|
|
261
|
+
self.appearing_cell_box_widget = QtWidgets.QWidget()
|
|
262
|
+
self.appearing_cell_box_widget.setStyleSheet(boxstylesheet)
|
|
263
|
+
|
|
264
|
+
# III/C/ Create widgets
|
|
265
|
+
self.first_move_threshold = Spinbox(min=0, max=1000000, val=self.parent().po.all['first_move_threshold_in_mm²'],
|
|
266
|
+
decimals=6, night_mode=self.parent().po.all['night_mode'])
|
|
267
|
+
self.first_move_threshold_label = FixedText('Minimal size to detect a cell/colony',
|
|
268
|
+
tip="In mm². All appearing cell/colony lesser than this value will be considered as noise",
|
|
269
|
+
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
|
+
self.do_automatic_size_thresholding = Checkbox(self.parent().po.all['automatic_size_thresholding'])
|
|
273
|
+
self.do_automatic_size_thresholding_label = FixedText('Automatic size threshold for appearance/motion',
|
|
274
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
275
|
+
self.do_automatic_size_thresholding.stateChanged.connect(self.do_automatic_size_thresholding_changed)
|
|
276
|
+
self.appearing_selection = Combobox(["largest", "most_central"], night_mode=self.parent().po.all['night_mode'])
|
|
277
|
+
self.appearing_selection_label = FixedText('Appearance detection method',
|
|
278
|
+
tip="When specimen(s) are invisible at the beginning of the experiment and appear progressively",
|
|
279
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
280
|
+
self.appearing_selection.setCurrentText(self.parent().po.vars['appearance_detection_method'])
|
|
281
|
+
self.appearing_selection.setFixedWidth(190)
|
|
282
|
+
|
|
283
|
+
# III/D/ Arrange widgets in the box
|
|
284
|
+
curr_box_row = 0
|
|
285
|
+
self.appearing_cell_box_layout.addWidget(self.do_automatic_size_thresholding, curr_box_row, 0)
|
|
286
|
+
self.appearing_cell_box_layout.addWidget(self.do_automatic_size_thresholding_label, curr_box_row, 1)
|
|
287
|
+
curr_box_row += 1
|
|
288
|
+
self.appearing_cell_box_layout.addWidget(self.first_move_threshold, curr_box_row, 0)
|
|
289
|
+
self.appearing_cell_box_layout.addWidget(self.first_move_threshold_label, curr_box_row, 1)
|
|
290
|
+
curr_box_row += 1
|
|
291
|
+
self.appearing_cell_box_layout.addWidget(self.appearing_selection, curr_box_row, 0)
|
|
292
|
+
self.appearing_cell_box_layout.addWidget(self.appearing_selection_label, curr_box_row, 1)
|
|
293
|
+
curr_box_row += 1
|
|
294
|
+
|
|
295
|
+
self.appearing_cell_box_widget.setLayout(self.appearing_cell_box_layout)
|
|
296
|
+
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
|
+
|
|
300
|
+
# IV/ Fourth box: Oscillation period:#
|
|
301
|
+
# IV/A/ Title
|
|
302
|
+
self.oscillation_label = FixedText('Oscillatory parameters:', tip="",
|
|
303
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
304
|
+
self.left_col_layout.addWidget(self.oscillation_label)
|
|
305
|
+
|
|
306
|
+
self.oscillation_period_layout = QtWidgets.QGridLayout()
|
|
307
|
+
self.oscillation_period_widget = QtWidgets.QWidget()
|
|
308
|
+
self.oscillation_period_widget.setStyleSheet(boxstylesheet)
|
|
309
|
+
|
|
310
|
+
self.oscillation_period = Spinbox(min=0, max=10000, val=self.parent().po.vars['expected_oscillation_period'], decimals=2,
|
|
311
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
312
|
+
self.oscillation_period_label = FixedText('Expected oscillation period (min)',
|
|
313
|
+
tip="If one expect biotic oscillations to occur",
|
|
314
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
315
|
+
|
|
316
|
+
self.minimal_oscillating_cluster_size = Spinbox(min=1, max=1000000000, decimals=0, val=self.parent().po.vars['minimal_oscillating_cluster_size'],
|
|
317
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
318
|
+
self.minimal_oscillating_cluster_size_label = FixedText('Minimal oscillating cluster size',
|
|
319
|
+
tip="In pixels\nWhen analyzing oscillations within the detected specimen(s)\nCellects looks for clusters of pixels that oscillate synchronously\nThis parameter sets the minimal size (in pixels) of these clusters.",
|
|
320
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
321
|
+
|
|
322
|
+
self.oscillation_period_layout.addWidget(self.oscillation_period, 0, 0)
|
|
323
|
+
self.oscillation_period_layout.addWidget(self.oscillation_period_label, 0, 1)
|
|
324
|
+
self.oscillation_period_layout.addWidget(self.minimal_oscillating_cluster_size, 1, 0)
|
|
325
|
+
self.oscillation_period_layout.addWidget(self.minimal_oscillating_cluster_size_label, 1, 1)
|
|
326
|
+
|
|
327
|
+
self.oscillation_period_widget.setLayout(self.oscillation_period_layout)
|
|
328
|
+
self.left_col_layout.addWidget(self.oscillation_period_widget)
|
|
329
|
+
|
|
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
|
+
# I/ First box: Scales
|
|
409
|
+
# I/A/ Title
|
|
410
|
+
|
|
411
|
+
self.right_scroll_table = QtWidgets.QScrollArea() # QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
|
|
412
|
+
self.right_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
|
413
|
+
self.right_scroll_table.setMinimumHeight(150)#self.parent().im_max_height - 100
|
|
414
|
+
self.right_scroll_table.setFrameShape(QtWidgets.QFrame.NoFrame)
|
|
415
|
+
self.right_scroll_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
416
|
+
self.right_scroll_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
self.scale_box_label = FixedText('Spatio-temporal scaling:', tip="",
|
|
420
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
421
|
+
self.right_col_layout.addWidget(self.scale_box_label)
|
|
422
|
+
# self.layout.addWidget(self.scale_box_label, curr_row_2nd_col, 4)
|
|
423
|
+
# curr_row_2nd_col += 1
|
|
424
|
+
# I/B/ Create the box
|
|
425
|
+
self.scale_box_layout = QtWidgets.QGridLayout()
|
|
426
|
+
self.scale_box_widget = QtWidgets.QWidget()
|
|
427
|
+
self.scale_box_widget.setStyleSheet(boxstylesheet)
|
|
428
|
+
# I/C/ Create widgets
|
|
429
|
+
|
|
430
|
+
self.extract_time = Checkbox(self.parent().po.all['extract_time_interval'])
|
|
431
|
+
self.extract_time.clicked.connect(self.extract_time_is_clicked)
|
|
432
|
+
|
|
433
|
+
self.time_step = Spinbox(min=0, max=100000, val=self.parent().po.vars['time_step'], decimals=3,
|
|
434
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
435
|
+
self.time_step.setFixedWidth(60)
|
|
436
|
+
if self.parent().po.all['extract_time_interval']:
|
|
437
|
+
self.time_step.setVisible(False)
|
|
438
|
+
self.time_step_label = FixedText('Automatically extract time interval between images',
|
|
439
|
+
tip="Uses the exif data of the images (if available), to extract these intervals\nOtherwise, default time interval is 1 min",
|
|
440
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
441
|
+
else:
|
|
442
|
+
self.time_step_label = FixedText('Set the time interval between images',
|
|
443
|
+
tip="In minutes",
|
|
444
|
+
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
|
+
self.pixels_to_mm = Checkbox(self.parent().po.vars['output_in_mm'])
|
|
451
|
+
self.pixels_to_mm_label = FixedText('Convert areas and distances from pixels to mm',
|
|
452
|
+
tip="Check if you want output variables to be in mm\nUncheck if you want output variables to be in pixels",
|
|
453
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
454
|
+
# I/D/ Arrange widgets in the box
|
|
455
|
+
self.scale_box_layout.addWidget(self.extract_time, 0, 0)
|
|
456
|
+
self.scale_box_layout.addWidget(self.time_step_label, 0, 1)
|
|
457
|
+
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
|
+
self.scale_box_layout.addWidget(self.pixels_to_mm, 2, 0)
|
|
461
|
+
self.scale_box_layout.addWidget(self.pixels_to_mm_label, 2, 1)
|
|
462
|
+
self.scale_box_widget.setLayout(self.scale_box_layout)
|
|
463
|
+
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
|
+
|
|
467
|
+
# IV/ Fourth box: Computer resources
|
|
468
|
+
# IV/A/ Title
|
|
469
|
+
self.resources_label = FixedText('Computer resources:', tip="",
|
|
470
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
471
|
+
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
|
+
# IV/B/ Create the box
|
|
476
|
+
self.resources_box_layout = QtWidgets.QGridLayout()
|
|
477
|
+
self.resources_box_widget = QtWidgets.QWidget()
|
|
478
|
+
self.resources_box_widget.setStyleSheet(boxstylesheet)
|
|
479
|
+
|
|
480
|
+
# IV/C/ Create widgets
|
|
481
|
+
self.do_multiprocessing = Checkbox(self.parent().po.all['do_multiprocessing'])
|
|
482
|
+
self.do_multiprocessing_label = FixedText('Run analysis in parallel', tip="Allow the use of more than one core of the computer processor", night_mode=self.parent().po.all['night_mode'])
|
|
483
|
+
self.do_multiprocessing.stateChanged.connect(self.do_multiprocessing_is_clicked)
|
|
484
|
+
self.max_core_nb = Spinbox(min=0, max=256, val=self.parent().po.all['cores'],
|
|
485
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
486
|
+
self.max_core_nb_label = FixedText('Proc max core number', night_mode=self.parent().po.all['night_mode'])
|
|
487
|
+
# self.max_core_nb.setVisible(self.parent().po.all['do_multiprocessing'])
|
|
488
|
+
# self.max_core_nb_label.setVisible(self.parent().po.all['do_multiprocessing'])
|
|
489
|
+
|
|
490
|
+
self.min_memory_left = Spinbox(min=0, max=1024, val=self.parent().po.vars['min_ram_free'], decimals=1,
|
|
491
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
492
|
+
self.min_memory_left_label = FixedText('Minimal RAM let free (Go)', night_mode=self.parent().po.all['night_mode'])
|
|
493
|
+
|
|
494
|
+
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('Lose accuracy to save RAM',
|
|
496
|
+
tip="Use 8 bits instead of 64 to study each pixel",
|
|
497
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
498
|
+
|
|
499
|
+
# IV/D/ Arrange widgets in the box
|
|
500
|
+
self.resources_box_layout.addWidget(self.do_multiprocessing, 0, 0)
|
|
501
|
+
self.resources_box_layout.addWidget(self.do_multiprocessing_label, 0, 1)
|
|
502
|
+
self.resources_box_layout.addWidget(self.max_core_nb, 1, 0)
|
|
503
|
+
self.resources_box_layout.addWidget(self.max_core_nb_label, 1, 1)
|
|
504
|
+
self.resources_box_layout.addWidget(self.min_memory_left, 2, 0)
|
|
505
|
+
self.resources_box_layout.addWidget(self.min_memory_left_label, 2, 1)
|
|
506
|
+
self.resources_box_layout.addWidget(self.lose_accuracy_to_save_memory, 3, 0)
|
|
507
|
+
self.resources_box_layout.addWidget(self.lose_accuracy_to_save_memory_label, 3, 1)
|
|
508
|
+
self.resources_box_widget.setLayout(self.resources_box_layout)
|
|
509
|
+
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
|
+
# V/ Fifth box: Video saving
|
|
514
|
+
# V/A/ Title
|
|
515
|
+
self.video_saving_label = FixedText('Video saving:', tip="",
|
|
516
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
517
|
+
self.right_col_layout.addWidget(self.video_saving_label)
|
|
518
|
+
# self.layout.addWidget(self.video_saving_label, curr_row_2nd_col, 4)
|
|
519
|
+
# curr_row_2nd_col += 1
|
|
520
|
+
# V/B/ Create the box
|
|
521
|
+
self.video_saving_layout = QtWidgets.QGridLayout()
|
|
522
|
+
self.video_saving_widget = QtWidgets.QWidget()
|
|
523
|
+
self.video_saving_widget.setStyleSheet(boxstylesheet)
|
|
524
|
+
|
|
525
|
+
# V/C/ Create widgets
|
|
526
|
+
self.video_fps = Spinbox(min=0, max=10000, val=self.parent().po.vars['video_fps'], decimals=2,
|
|
527
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
528
|
+
self.video_fps_label = FixedText('Video fps', night_mode=self.parent().po.all['night_mode'])
|
|
529
|
+
# self.overwrite_unaltered_videos = Checkbox(self.parent().po.all['overwrite_unaltered_videos'])
|
|
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'])
|
|
531
|
+
self.keep_unaltered_videos = Checkbox(self.parent().po.vars['keep_unaltered_videos'])
|
|
532
|
+
self.keep_unaltered_videos_label = FixedText('Keep unaltered videos', tip="Unaltered videos (.npy) takes a lot of hard drive space\nUsers should only keep these videos\nif they plan to redo the analysis soon and faster", night_mode=self.parent().po.all['night_mode'])
|
|
533
|
+
self.save_processed_videos = Checkbox(self.parent().po.vars['save_processed_videos'])
|
|
534
|
+
self.save_processed_videos_label = FixedText('Save processed videos', tip="Processed videos allow to check analysis accuracy\nThey do not take a lot of space", night_mode=self.parent().po.all['night_mode'])
|
|
535
|
+
|
|
536
|
+
# V/D/ Arrange widgets in the box
|
|
537
|
+
curr_box_row = 0
|
|
538
|
+
self.video_saving_layout.addWidget(self.video_fps, curr_box_row, 0)
|
|
539
|
+
self.video_saving_layout.addWidget(self.video_fps_label, curr_box_row, 1)
|
|
540
|
+
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
|
+
self.video_saving_layout.addWidget(self.keep_unaltered_videos, curr_box_row, 0)
|
|
545
|
+
self.video_saving_layout.addWidget(self.keep_unaltered_videos_label, curr_box_row, 1)
|
|
546
|
+
curr_box_row += 1
|
|
547
|
+
self.video_saving_layout.addWidget(self.save_processed_videos, curr_box_row, 0)
|
|
548
|
+
self.video_saving_layout.addWidget(self.save_processed_videos_label, curr_box_row, 1)
|
|
549
|
+
curr_box_row += 1
|
|
550
|
+
|
|
551
|
+
self.video_saving_widget.setLayout(self.video_saving_layout)
|
|
552
|
+
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
|
+
|
|
556
|
+
# VII/ Seventh box: csc
|
|
557
|
+
# 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
|
+
# VII/C/ Create widgets
|
|
565
|
+
self.generate_csc_editing()
|
|
566
|
+
# VII/D/ Arrange widgets in the box
|
|
567
|
+
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
|
+
|
|
571
|
+
# VIII/ Finalize layout and add the night mode option and the ok button
|
|
572
|
+
self.left_col_layout.addItem(self.vertical_space)
|
|
573
|
+
self.right_col_layout.addItem(self.vertical_space)
|
|
574
|
+
self.left_col_widget.setLayout(self.left_col_layout)
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
self.right_col_widget.setLayout(self.right_col_layout)
|
|
578
|
+
self.central_layout = QtWidgets.QHBoxLayout()
|
|
579
|
+
self.central_layout.addItem(self.horizontal_space)
|
|
580
|
+
#self.central_layout.addWidget(self.left_col_widget)
|
|
581
|
+
|
|
582
|
+
self.left_scroll_table.setWidget(self.left_col_widget)
|
|
583
|
+
self.left_scroll_table.setWidgetResizable(True)
|
|
584
|
+
self.central_layout.addWidget(self.left_scroll_table)
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
self.central_layout.addItem(self.horizontal_space)
|
|
588
|
+
self.right_scroll_table.setWidget(self.right_col_widget)
|
|
589
|
+
self.right_scroll_table.setWidgetResizable(True)
|
|
590
|
+
self.central_layout.addWidget(self.right_scroll_table)
|
|
591
|
+
# self.central_layout.addWidget(self.right_col_widget)
|
|
592
|
+
self.central_layout.addItem(self.horizontal_space)
|
|
593
|
+
self.central_widget = QtWidgets.QWidget()
|
|
594
|
+
self.central_widget.setLayout(self.central_layout)
|
|
595
|
+
self.layout.addWidget(self.central_widget)
|
|
596
|
+
self.layout.addItem(self.vertical_space)
|
|
597
|
+
# Last row
|
|
598
|
+
self.last_row_layout = QtWidgets.QHBoxLayout()
|
|
599
|
+
self.last_row_widget = QtWidgets.QWidget()
|
|
600
|
+
self.night_mode_cb = Checkbox(self.parent().po.all['night_mode'])
|
|
601
|
+
self.night_mode_cb.clicked.connect(self.night_mode_is_clicked)
|
|
602
|
+
self.night_mode_label = FixedText('Night mode', night_mode=self.parent().po.all['night_mode'])
|
|
603
|
+
self.reset_all_settings = PButton("Reset all settings", night_mode=self.parent().po.all['night_mode'])
|
|
604
|
+
self.reset_all_settings.clicked.connect(self.reset_all_settings_is_clicked)
|
|
605
|
+
self.message = FixedText('', night_mode=self.parent().po.all['night_mode'])
|
|
606
|
+
self.cancel = PButton('Cancel', night_mode=self.parent().po.all['night_mode'])
|
|
607
|
+
self.cancel.clicked.connect(self.cancel_is_clicked)
|
|
608
|
+
self.ok = PButton('Ok', night_mode=self.parent().po.all['night_mode'])
|
|
609
|
+
self.ok.clicked.connect(self.ok_is_clicked)
|
|
610
|
+
self.last_row_layout.addWidget(self.night_mode_cb)
|
|
611
|
+
self.last_row_layout.addWidget(self.night_mode_label)
|
|
612
|
+
self.last_row_layout.addWidget(self.reset_all_settings)
|
|
613
|
+
self.last_row_layout.addItem(self.horizontal_space)
|
|
614
|
+
self.last_row_layout.addWidget(self.message)
|
|
615
|
+
self.last_row_layout.addWidget(self.cancel)
|
|
616
|
+
self.last_row_layout.addWidget(self.ok)
|
|
617
|
+
self.last_row_widget.setLayout(self.last_row_layout)
|
|
618
|
+
self.layout.addWidget(self.last_row_widget)
|
|
619
|
+
|
|
620
|
+
self.setLayout(self.layout)
|
|
621
|
+
|
|
622
|
+
def display_conditionally_visible_widgets(self):
|
|
623
|
+
self.max_core_nb.setVisible(self.parent().po.all['do_multiprocessing'])
|
|
624
|
+
self.max_core_nb_label.setVisible(self.parent().po.all['do_multiprocessing'])
|
|
625
|
+
self.first_move_threshold.setVisible(not self.parent().po.all['automatic_size_thresholding'])
|
|
626
|
+
self.first_move_threshold_label.setVisible(not self.parent().po.all['automatic_size_thresholding'])
|
|
627
|
+
connect_distant_shape = self.parent().po.all['connect_distant_shape_during_segmentation']
|
|
628
|
+
do_use_max_size = self.parent().po.vars['max_size_for_connection'] is not None and connect_distant_shape
|
|
629
|
+
do_use_min_size = self.parent().po.vars['min_size_for_connection'] is not None and connect_distant_shape
|
|
630
|
+
self.detection_range_factor.setVisible(connect_distant_shape)
|
|
631
|
+
self.detection_range_factor_label.setVisible(connect_distant_shape)
|
|
632
|
+
self.use_max_size.setVisible(connect_distant_shape)
|
|
633
|
+
self.use_min_size.setVisible(connect_distant_shape)
|
|
634
|
+
self.use_max_size_label.setVisible(connect_distant_shape)
|
|
635
|
+
self.use_min_size_label.setVisible(connect_distant_shape)
|
|
636
|
+
|
|
637
|
+
self.max_size_for_connection.setVisible(do_use_max_size)
|
|
638
|
+
self.max_size_for_connection_label.setVisible(do_use_max_size)
|
|
639
|
+
self.min_size_for_connection.setVisible(do_use_min_size)
|
|
640
|
+
self.min_size_for_connection_label.setVisible(do_use_min_size)
|
|
641
|
+
self.display_more_than_two_colors_option()
|
|
642
|
+
|
|
643
|
+
if self.parent().po.vars['convert_for_motion'] is not None:
|
|
644
|
+
self.update_csc_editing_display()
|
|
645
|
+
else:
|
|
646
|
+
self.row1[0].setCurrentIndex(4)
|
|
647
|
+
self.row1[3].setValue(1)
|
|
648
|
+
self.row21[0].setCurrentIndex(0)
|
|
649
|
+
self.row21[3].setValue(0)
|
|
650
|
+
|
|
651
|
+
def subtract_background_check(self):
|
|
652
|
+
self.parent().po.motion = None
|
|
653
|
+
if self.subtract_background.isChecked():
|
|
654
|
+
self.parent().po.first_exp_ready_to_run = False
|
|
655
|
+
|
|
656
|
+
def prevent_fast_growth_near_periphery_check(self):
|
|
657
|
+
checked_status = self.prevent_fast_growth_near_periphery.isChecked()
|
|
658
|
+
self.periphery_width.setVisible(checked_status)
|
|
659
|
+
self.periphery_width_label.setVisible(checked_status)
|
|
660
|
+
self.max_periphery_growth.setVisible(checked_status)
|
|
661
|
+
self.max_periphery_growth_label.setVisible(checked_status)
|
|
662
|
+
|
|
663
|
+
def do_automatic_size_thresholding_changed(self):
|
|
664
|
+
""" Triggered when do_automatic_size_thresholding check status changes"""
|
|
665
|
+
self.first_move_threshold.setVisible(not self.do_automatic_size_thresholding.isChecked())
|
|
666
|
+
self.first_move_threshold_label.setVisible(not self.do_automatic_size_thresholding.isChecked())
|
|
667
|
+
|
|
668
|
+
def extract_time_is_clicked(self):
|
|
669
|
+
self.time_step.setVisible(not self.extract_time.isChecked())
|
|
670
|
+
if self.extract_time.isChecked():
|
|
671
|
+
self.time_step_label.setText("Automatically extract time interval between images")
|
|
672
|
+
self.time_step_label.setToolTip("Uses the exif data of the images (if available), to extract these intervals\nOtherwise, default time interval is 1 min")
|
|
673
|
+
else:
|
|
674
|
+
self.time_step_label.setText("Set the time interval between images")
|
|
675
|
+
self.time_step_label.setToolTip("In minutes")
|
|
676
|
+
|
|
677
|
+
def do_multiprocessing_is_clicked(self):
|
|
678
|
+
self.max_core_nb.setVisible(self.do_multiprocessing.isChecked())
|
|
679
|
+
self.max_core_nb_label.setVisible(self.do_multiprocessing.isChecked())
|
|
680
|
+
|
|
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
|
+
def do_distant_shape_int_changed(self):
|
|
686
|
+
""" Triggered when connect_distant_shape_during_segmentation check status changes"""
|
|
687
|
+
do_distant_shape_int = self.connect_distant_shape_during_segmentation.isChecked()
|
|
688
|
+
self.detection_range_factor.setVisible(do_distant_shape_int)
|
|
689
|
+
if do_distant_shape_int:
|
|
690
|
+
self.detection_range_factor.setValue(2)
|
|
691
|
+
self.detection_range_factor_label.setVisible(do_distant_shape_int)
|
|
692
|
+
self.use_max_size.setVisible(do_distant_shape_int)
|
|
693
|
+
self.use_min_size.setVisible(do_distant_shape_int)
|
|
694
|
+
self.use_max_size_label.setVisible(do_distant_shape_int)
|
|
695
|
+
self.use_min_size_label.setVisible(do_distant_shape_int)
|
|
696
|
+
do_use_max_size = do_distant_shape_int and self.use_max_size.isChecked()
|
|
697
|
+
self.max_size_for_connection.setVisible(do_use_max_size)
|
|
698
|
+
self.max_size_for_connection_label.setVisible(do_use_max_size)
|
|
699
|
+
do_use_min_size = do_distant_shape_int and self.use_min_size.isChecked()
|
|
700
|
+
self.min_size_for_connection.setVisible(do_use_min_size)
|
|
701
|
+
self.min_size_for_connection_label.setVisible(do_use_min_size)
|
|
702
|
+
|
|
703
|
+
def use_max_size_changed(self):
|
|
704
|
+
""" Triggered when use_max_size check status changes"""
|
|
705
|
+
do_use_max_size = self.use_max_size.isChecked()
|
|
706
|
+
self.max_size_for_connection.setVisible(do_use_max_size)
|
|
707
|
+
self.max_size_for_connection_label.setVisible(do_use_max_size)
|
|
708
|
+
if do_use_max_size:
|
|
709
|
+
self.max_size_for_connection.setValue(300)
|
|
710
|
+
|
|
711
|
+
def use_min_size_changed(self):
|
|
712
|
+
""" Triggered when use_min_size check status changes"""
|
|
713
|
+
do_use_min_size = self.use_min_size.isChecked()
|
|
714
|
+
self.min_size_for_connection.setVisible(do_use_min_size)
|
|
715
|
+
self.min_size_for_connection_label.setVisible(do_use_min_size)
|
|
716
|
+
if do_use_min_size:
|
|
717
|
+
self.min_size_for_connection.setValue(30)
|
|
718
|
+
|
|
719
|
+
def generate_csc_editing(self):
|
|
720
|
+
# self.edit_layout = QtWidgets.QGridLayout()
|
|
721
|
+
self.edit_widget = QtWidgets.QWidget()
|
|
722
|
+
# self.edit_widget.setVisible(False)
|
|
723
|
+
# self.edit_widget.setStyleSheet(boxstylesheet)
|
|
724
|
+
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
|
+
self.csc_table_widget = QtWidgets.QWidget()
|
|
736
|
+
self.csc_table_layout = QtWidgets.QVBoxLayout()
|
|
737
|
+
|
|
738
|
+
# 2) Titles
|
|
739
|
+
# self.edit_labels_widget = QtWidgets.QWidget()
|
|
740
|
+
# self.edit_labels_widget.setFixedHeight(50)
|
|
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="",
|
|
758
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
759
|
+
self.video_csc_label.setFixedHeight(30)
|
|
760
|
+
self.csc_table_layout.addWidget(self.video_csc_label)
|
|
761
|
+
|
|
762
|
+
self.both_csc_widget = QtWidgets.QWidget()
|
|
763
|
+
self.both_csc_layout = QtWidgets.QHBoxLayout()
|
|
764
|
+
# 3) First CSC
|
|
765
|
+
self.first_csc_widget = QtWidgets.QWidget()
|
|
766
|
+
self.first_csc_layout = QtWidgets.QGridLayout()
|
|
767
|
+
self.row1 = self.one_csc_editing()
|
|
768
|
+
self.row1[4].clicked.connect(self.display_row2)
|
|
769
|
+
self.row2 = self.one_csc_editing()
|
|
770
|
+
self.row2[4].clicked.connect(self.display_row3)
|
|
771
|
+
self.row3 = self.one_csc_editing()# Second CSC
|
|
772
|
+
self.logical_operator_between_combination_result = Combobox(["None", "Or", "And", "Xor"],
|
|
773
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
774
|
+
self.logical_operator_between_combination_result.setCurrentText(self.parent().po.vars['convert_for_motion']['logical'])
|
|
775
|
+
self.logical_operator_between_combination_result.currentTextChanged.connect(self.logical_op_changed)
|
|
776
|
+
self.logical_operator_between_combination_result.setFixedWidth(100)
|
|
777
|
+
# self.logical_operator_between_combination_result.cha
|
|
778
|
+
self.logical_operator_label = FixedText("Logical operator", halign='c', tip="Between selected color space combinations",
|
|
779
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
780
|
+
|
|
781
|
+
self.row21 = self.one_csc_editing()
|
|
782
|
+
self.row21[4].clicked.connect(self.display_row22)
|
|
783
|
+
self.row22 = self.one_csc_editing()
|
|
784
|
+
self.row22[4].clicked.connect(self.display_row23)
|
|
785
|
+
self.row23 = self.one_csc_editing()
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
for i in range(5):
|
|
789
|
+
self.first_csc_layout.addWidget(self.row1[i], 0, i, 1, 1)
|
|
790
|
+
self.first_csc_layout.addWidget(self.row2[i], 1, i, 1, 1)
|
|
791
|
+
self.first_csc_layout.addWidget(self.row3[i], 2, i, 1, 1)
|
|
792
|
+
self.row1[i].setVisible(False)
|
|
793
|
+
self.row2[i].setVisible(False)
|
|
794
|
+
self.row3[i].setVisible(False)
|
|
795
|
+
self.first_csc_layout.setHorizontalSpacing(0)
|
|
796
|
+
self.first_csc_layout.addItem(self.horizontal_space, 0, 5, 3, 1)
|
|
797
|
+
self.first_csc_widget.setLayout(self.first_csc_layout)
|
|
798
|
+
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
|
+
|
|
803
|
+
# 5) Second CSC
|
|
804
|
+
self.second_csc_widget = QtWidgets.QWidget()
|
|
805
|
+
self.second_csc_layout = QtWidgets.QGridLayout()
|
|
806
|
+
for i in range(5):
|
|
807
|
+
self.second_csc_layout.addWidget(self.row21[i], 0, i, 1, 1)
|
|
808
|
+
self.second_csc_layout.addWidget(self.row22[i], 1, i, 1, 1)
|
|
809
|
+
self.second_csc_layout.addWidget(self.row23[i], 2, i, 1, 1)
|
|
810
|
+
self.row21[i].setVisible(False)
|
|
811
|
+
self.row22[i].setVisible(False)
|
|
812
|
+
self.row23[i].setVisible(False)
|
|
813
|
+
self.second_csc_layout.setHorizontalSpacing(0)
|
|
814
|
+
self.second_csc_layout.addItem(self.horizontal_space, 0, 5, 3, 1)
|
|
815
|
+
self.second_csc_widget.setLayout(self.second_csc_layout)
|
|
816
|
+
self.both_csc_layout.addItem(self.horizontal_space)
|
|
817
|
+
self.both_csc_layout.addWidget(self.second_csc_widget)
|
|
818
|
+
self.both_csc_widget.setLayout(self.both_csc_layout)
|
|
819
|
+
self.csc_table_layout.addWidget(self.both_csc_widget)
|
|
820
|
+
# self.csc_table_layout.addWidget(self.second_csc_widget)
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
# 4) logical_operator
|
|
824
|
+
self.logical_op_widget = QtWidgets.QWidget()
|
|
825
|
+
self.logical_op_widget.setFixedHeight(30)
|
|
826
|
+
self.logical_op_layout = QtWidgets.QHBoxLayout()
|
|
827
|
+
self.logical_op_layout.addWidget(self.logical_operator_label)
|
|
828
|
+
self.logical_op_layout.addWidget(self.logical_operator_between_combination_result)
|
|
829
|
+
self.logical_op_layout.addItem(self.horizontal_space)
|
|
830
|
+
self.logical_operator_between_combination_result.setVisible(False)
|
|
831
|
+
self.logical_operator_label.setVisible(False)
|
|
832
|
+
self.logical_op_widget.setLayout(self.logical_op_layout)
|
|
833
|
+
self.logical_op_widget.setFixedHeight(50)
|
|
834
|
+
self.csc_table_layout.addWidget(self.logical_op_widget)
|
|
835
|
+
# self.edit_layout.addWidget(self.logical_op_widget)
|
|
836
|
+
|
|
837
|
+
# 6) Open the more_than_2_colors row layout
|
|
838
|
+
self.more_than_2_colors_widget = QtWidgets.QWidget()
|
|
839
|
+
self.more_than_2_colors_layout = QtWidgets.QHBoxLayout()
|
|
840
|
+
self.more_than_two_colors = Checkbox(self.parent().po.all["more_than_two_colors"])
|
|
841
|
+
self.more_than_two_colors.setStyleSheet("margin-left:0%; margin-right:-10%;")
|
|
842
|
+
self.more_than_two_colors.stateChanged.connect(self.display_more_than_two_colors_option)
|
|
843
|
+
|
|
844
|
+
self.more_than_two_colors_label = FixedText("Heterogeneous back",
|
|
845
|
+
tip="The program will split the image into categories", night_mode=self.parent().po.all['night_mode'])
|
|
846
|
+
self.more_than_two_colors_label.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
847
|
+
# self.more_than_two_colors_label.setFixedWidth(300)
|
|
848
|
+
self.more_than_two_colors_label.setAlignment(QtCore.Qt.AlignLeft)
|
|
849
|
+
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
|
+
self.more_than_2_colors_layout.addWidget(self.more_than_two_colors)
|
|
856
|
+
self.more_than_2_colors_layout.addWidget(self.more_than_two_colors_label)
|
|
857
|
+
self.more_than_2_colors_layout.addWidget(self.distinct_colors_number)
|
|
858
|
+
self.more_than_2_colors_layout.addItem(self.horizontal_space)
|
|
859
|
+
self.more_than_2_colors_widget.setLayout(self.more_than_2_colors_layout)
|
|
860
|
+
self.more_than_2_colors_widget.setFixedHeight(50)
|
|
861
|
+
self.csc_table_layout.addWidget(self.more_than_2_colors_widget)
|
|
862
|
+
self.csc_table_layout.addItem(self.vertical_space)
|
|
863
|
+
self.csc_table_widget.setLayout(self.csc_table_layout)
|
|
864
|
+
|
|
865
|
+
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
|
+
|
|
877
|
+
self.edit_widget.setLayout(self.edit_layout)
|
|
878
|
+
|
|
879
|
+
def one_csc_editing(self):
|
|
880
|
+
widget_list = []
|
|
881
|
+
widget_list.insert(0, Combobox(["None", "bgr", "hsv", "hls", "lab", "luv", "yuv"],
|
|
882
|
+
night_mode=self.parent().po.all['night_mode']))
|
|
883
|
+
widget_list[0].setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
884
|
+
widget_list[0].setFixedWidth(100)
|
|
885
|
+
for i in [1, 2, 3]:
|
|
886
|
+
widget_list.insert(i, Spinbox(min=-126, max=126, val=0, night_mode=self.parent().po.all['night_mode']))
|
|
887
|
+
widget_list[i].setFixedWidth(45)
|
|
888
|
+
widget_list.insert(i + 1, PButton("+", night_mode=self.parent().po.all['night_mode']))
|
|
889
|
+
|
|
890
|
+
return widget_list
|
|
891
|
+
|
|
892
|
+
def logical_op_changed(self):
|
|
893
|
+
# show = self.logical_operator_between_combination_result.currentText() != 'None'
|
|
894
|
+
if self.logical_operator_between_combination_result.currentText() == 'None':
|
|
895
|
+
self.row21[0].setVisible(False)
|
|
896
|
+
self.row21[0].setCurrentIndex(0)
|
|
897
|
+
for i1 in [1, 2, 3]:
|
|
898
|
+
self.row21[i1].setVisible(False)
|
|
899
|
+
self.row21[i1].setValue(0)
|
|
900
|
+
self.row21[i1 + 1].setVisible(False)
|
|
901
|
+
|
|
902
|
+
self.row22[0].setVisible(False)
|
|
903
|
+
self.row22[0].setCurrentIndex(0)
|
|
904
|
+
for i1 in [1, 2, 3]:
|
|
905
|
+
self.row22[i1].setVisible(False)
|
|
906
|
+
self.row22[i1].setValue(0)
|
|
907
|
+
self.row22[i1 + 1].setVisible(False)
|
|
908
|
+
|
|
909
|
+
self.row23[0].setVisible(False)
|
|
910
|
+
self.row23[0].setCurrentIndex(0)
|
|
911
|
+
for i1 in [1, 2, 3]:
|
|
912
|
+
self.row23[i1].setVisible(False)
|
|
913
|
+
self.row23[i1].setValue(0)
|
|
914
|
+
self.row23[i1 + 1].setVisible(False)
|
|
915
|
+
else:
|
|
916
|
+
self.row21[0].setVisible(True)
|
|
917
|
+
for i1 in [1, 2, 3]:
|
|
918
|
+
self.row21[i1].setVisible(True)
|
|
919
|
+
self.row21[i1 + 1].setVisible(True)
|
|
920
|
+
|
|
921
|
+
def display_logical_operator(self):
|
|
922
|
+
self.logical_operator_between_combination_result.setVisible(True)
|
|
923
|
+
self.logical_operator_label.setVisible(True)
|
|
924
|
+
|
|
925
|
+
def display_row2(self):
|
|
926
|
+
self.row1[4].setVisible(False)
|
|
927
|
+
for i in range(5):
|
|
928
|
+
self.row2[i].setVisible(True)
|
|
929
|
+
self.display_logical_operator()
|
|
930
|
+
|
|
931
|
+
def display_row3(self):
|
|
932
|
+
self.row2[4].setVisible(False)
|
|
933
|
+
for i in range(4):
|
|
934
|
+
self.row3[i].setVisible(True)
|
|
935
|
+
self.display_logical_operator()
|
|
936
|
+
|
|
937
|
+
def display_row22(self):
|
|
938
|
+
self.row21[4].setVisible(False)
|
|
939
|
+
for i in range(5):
|
|
940
|
+
self.row22[i].setVisible(True)
|
|
941
|
+
self.display_logical_operator()
|
|
942
|
+
|
|
943
|
+
def display_row23(self):
|
|
944
|
+
self.row22[4].setVisible(False)
|
|
945
|
+
for i in range(4):
|
|
946
|
+
self.row23[i].setVisible(True)
|
|
947
|
+
self.display_logical_operator()
|
|
948
|
+
|
|
949
|
+
def update_csc_editing_display(self):
|
|
950
|
+
c_space_order = ["None", "bgr", "hsv", "hls", "lab", "luv", "yuv"]
|
|
951
|
+
remaining_c_spaces = []
|
|
952
|
+
row_number1 = 0
|
|
953
|
+
row_number2 = 0
|
|
954
|
+
for i, (k, v) in enumerate(self.parent().po.vars['convert_for_motion'].items()):
|
|
955
|
+
if k != "logical":
|
|
956
|
+
if k[-1] != "2":
|
|
957
|
+
if row_number1 == 0:
|
|
958
|
+
row_to_change = self.row1
|
|
959
|
+
elif row_number1 == 1:
|
|
960
|
+
row_to_change = self.row2
|
|
961
|
+
elif row_number1 == 2:
|
|
962
|
+
row_to_change = self.row3
|
|
963
|
+
else:
|
|
964
|
+
remaining_c_spaces.append(k + " " + str(v))
|
|
965
|
+
row_number1 += 1
|
|
966
|
+
current_row_number = row_number1
|
|
967
|
+
else:
|
|
968
|
+
if row_number2 == 0:
|
|
969
|
+
row_to_change = self.row21
|
|
970
|
+
elif row_number2 == 1:
|
|
971
|
+
row_to_change = self.row22
|
|
972
|
+
elif row_number2 == 2:
|
|
973
|
+
row_to_change = self.row23
|
|
974
|
+
else:
|
|
975
|
+
remaining_c_spaces.append(k + " " + str(v))
|
|
976
|
+
row_number2 += 1
|
|
977
|
+
current_row_number = row_number2
|
|
978
|
+
k = k[:-1]
|
|
979
|
+
if current_row_number <= 3:
|
|
980
|
+
row_to_change[0].setCurrentIndex(np.nonzero(np.isin(c_space_order, k))[0][0])
|
|
981
|
+
row_to_change[0].setVisible(True)
|
|
982
|
+
for i1, i2 in zip([1, 2, 3], [0, 1, 2]):
|
|
983
|
+
row_to_change[i1].setValue(v[i2])
|
|
984
|
+
row_to_change[i1].setVisible(True)
|
|
985
|
+
if current_row_number < 3:
|
|
986
|
+
row_to_change[i1 + 1].setVisible(True)
|
|
987
|
+
|
|
988
|
+
# If not all color space combinations are filled, put None and 0 in boxes
|
|
989
|
+
if row_number1 < 3:
|
|
990
|
+
self.row3[0].setVisible(False)
|
|
991
|
+
self.row3[0].setCurrentIndex(0)
|
|
992
|
+
for i1 in [1, 2, 3]:
|
|
993
|
+
self.row3[i1].setVisible(False)
|
|
994
|
+
self.row3[i1].setValue(0)
|
|
995
|
+
if row_number1 < 2:
|
|
996
|
+
self.row2[0].setVisible(False)
|
|
997
|
+
self.row2[0].setCurrentIndex(0)
|
|
998
|
+
for i1 in [1, 2, 3]:
|
|
999
|
+
self.row2[i1].setVisible(False)
|
|
1000
|
+
self.row2[i1].setValue(0)
|
|
1001
|
+
self.row2[i1 + 1].setVisible(False)
|
|
1002
|
+
|
|
1003
|
+
self.row1[4].setVisible(row_number1 == 1)
|
|
1004
|
+
self.row2[4].setVisible(row_number1 == 2)
|
|
1005
|
+
self.row21[4].setVisible(row_number2 == 1)
|
|
1006
|
+
self.row22[4].setVisible(row_number2 == 2)
|
|
1007
|
+
if row_number2 > 0:
|
|
1008
|
+
self.logical_operator_between_combination_result.setCurrentText(self.parent().po.vars['convert_for_motion']['logical'])
|
|
1009
|
+
if row_number2 == 0:
|
|
1010
|
+
self.logical_operator_between_combination_result.setCurrentText('None')
|
|
1011
|
+
self.logical_operator_between_combination_result.setVisible(False)
|
|
1012
|
+
self.logical_operator_label.setVisible(False)
|
|
1013
|
+
self.row21[0].setVisible(False)
|
|
1014
|
+
self.row21[0].setCurrentIndex(0)
|
|
1015
|
+
for i1 in [1, 2, 3]:
|
|
1016
|
+
self.row21[i1].setVisible(False)
|
|
1017
|
+
self.row21[i1].setValue(0)
|
|
1018
|
+
self.row21[i1 + 1].setVisible(False)
|
|
1019
|
+
|
|
1020
|
+
self.logical_operator_between_combination_result.setVisible((row_number2 > 0))
|
|
1021
|
+
self.logical_operator_label.setVisible((row_number2 > 0))
|
|
1022
|
+
|
|
1023
|
+
if row_number2 < 3:
|
|
1024
|
+
self.row23[0].setVisible(False)
|
|
1025
|
+
self.row23[0].setCurrentIndex(0)
|
|
1026
|
+
for i1 in [1, 2, 3]:
|
|
1027
|
+
self.row23[i1].setVisible(False)
|
|
1028
|
+
self.row23[i1].setValue(0)
|
|
1029
|
+
self.row23[i1 + 1].setVisible(False)
|
|
1030
|
+
self.row22[4].setVisible(False)
|
|
1031
|
+
if row_number2 < 2:
|
|
1032
|
+
self.row22[0].setVisible(False)
|
|
1033
|
+
self.row22[0].setCurrentIndex(0)
|
|
1034
|
+
for i1 in [1, 2, 3]:
|
|
1035
|
+
self.row22[i1].setVisible(False)
|
|
1036
|
+
self.row22[i1].setValue(0)
|
|
1037
|
+
self.row22[i1 + 1].setVisible(False)
|
|
1038
|
+
|
|
1039
|
+
def save_user_defined_csc(self):
|
|
1040
|
+
self.parent().po.vars['convert_for_motion'] = {}
|
|
1041
|
+
spaces = np.array((self.row1[0].currentText(), self.row2[0].currentText(), self.row3[0].currentText()))
|
|
1042
|
+
channels = np.array(
|
|
1043
|
+
((self.row1[1].value(), self.row1[2].value(), self.row1[3].value()),
|
|
1044
|
+
(self.row2[1].value(), self.row2[2].value(), self.row2[3].value()),
|
|
1045
|
+
(self.row3[1].value(), self.row3[2].value(), self.row3[3].value()),
|
|
1046
|
+
(self.row21[1].value(), self.row21[2].value(), self.row21[3].value()),
|
|
1047
|
+
(self.row22[1].value(), self.row22[2].value(), self.row22[3].value()),
|
|
1048
|
+
(self.row23[1].value(), self.row23[2].value(), self.row23[3].value())),
|
|
1049
|
+
dtype=np.int8)
|
|
1050
|
+
if self.logical_operator_between_combination_result.currentText() != 'None':
|
|
1051
|
+
spaces = np.concatenate((spaces, np.array((
|
|
1052
|
+
self.row21[0].currentText() + "2", self.row22[0].currentText() + "2",
|
|
1053
|
+
self.row23[0].currentText() + "2"))))
|
|
1054
|
+
channels = np.concatenate((channels, np.array(((self.row21[1].value(), self.row21[2].value(), self.row21[3].value()),
|
|
1055
|
+
(self.row22[1].value(), self.row22[2].value(), self.row22[3].value()),
|
|
1056
|
+
(self.row23[1].value(), self.row23[2].value(), self.row23[3].value())),
|
|
1057
|
+
dtype=np.int8)))
|
|
1058
|
+
self.parent().po.vars['convert_for_motion']['logical'] = self.logical_operator_between_combination_result.currentText()
|
|
1059
|
+
else:
|
|
1060
|
+
self.parent().po.vars['convert_for_motion']['logical'] = 'None'
|
|
1061
|
+
if not np.all(spaces == "None"):
|
|
1062
|
+
for i, space in enumerate(spaces):
|
|
1063
|
+
if space != "None" and space != "None2":
|
|
1064
|
+
self.parent().po.vars['convert_for_motion'][space] = channels[i, :]
|
|
1065
|
+
if len(self.parent().po.vars['convert_for_motion']) == 1 or channels.sum() == 0:
|
|
1066
|
+
self.csc_dict_is_empty = True
|
|
1067
|
+
else:
|
|
1068
|
+
self.csc_dict_is_empty = False
|
|
1069
|
+
|
|
1070
|
+
self.parent().po.all["more_than_two_colors"] = self.more_than_two_colors.isChecked()
|
|
1071
|
+
if self.more_than_two_colors.isChecked():
|
|
1072
|
+
self.parent().po.vars["color_number"] = int(self.distinct_colors_number.value())
|
|
1073
|
+
self.parent().videoanalysiswindow.select_option.setVisible(True)
|
|
1074
|
+
self.parent().videoanalysiswindow.select_option_label.setVisible(True)
|
|
1075
|
+
|
|
1076
|
+
def display_more_than_two_colors_option(self):
|
|
1077
|
+
if self.more_than_two_colors.isChecked():
|
|
1078
|
+
self.distinct_colors_number.setVisible(True)
|
|
1079
|
+
self.more_than_two_colors_label.setText("How many distinct colors?")
|
|
1080
|
+
self.distinct_colors_number.setValue(3)
|
|
1081
|
+
else:
|
|
1082
|
+
self.more_than_two_colors_label.setText("Heterogeneous background")
|
|
1083
|
+
self.distinct_colors_number.setVisible(False)
|
|
1084
|
+
self.distinct_colors_number.setValue(2)
|
|
1085
|
+
|
|
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
|
+
def night_mode_is_clicked(self):
|
|
1093
|
+
""" Triggered when night_mode_cb check status changes"""
|
|
1094
|
+
self.parent().po.all['night_mode'] = self.night_mode_cb.isChecked()
|
|
1095
|
+
self.message.setText('Close and restart Cellects to apply night or light mode')
|
|
1096
|
+
self.message.setStyleSheet("color: rgb(230, 145, 18)")
|
|
1097
|
+
|
|
1098
|
+
def reset_all_settings_is_clicked(self):
|
|
1099
|
+
if os.path.isfile('Data to run Cellects quickly.pkl'):
|
|
1100
|
+
os.remove('Data to run Cellects quickly.pkl')
|
|
1101
|
+
if os.path.isfile('PickleRick.pkl'):
|
|
1102
|
+
os.remove('PickleRick.pkl')
|
|
1103
|
+
if os.path.isfile('PickleRick0.pkl'):
|
|
1104
|
+
os.remove('PickleRick0.pkl')
|
|
1105
|
+
if os.path.isfile(Path(CELLECTS_DIR.parent / 'PickleRick.pkl')):
|
|
1106
|
+
os.remove(Path(CELLECTS_DIR.parent / 'PickleRick.pkl'))
|
|
1107
|
+
if os.path.isfile(Path(CELLECTS_DIR.parent / 'PickleRick0.pkl')):
|
|
1108
|
+
os.remove(Path(CELLECTS_DIR.parent / 'PickleRick0.pkl'))
|
|
1109
|
+
if os.path.isfile(Path(CONFIG_DIR / 'PickleRick1.pkl')):
|
|
1110
|
+
os.remove(Path(CONFIG_DIR / 'PickleRick1.pkl'))
|
|
1111
|
+
current_dir = os.getcwd()
|
|
1112
|
+
os.chdir(CONFIG_DIR)
|
|
1113
|
+
DefaultDicts().save_as_pkl(self.parent().po)
|
|
1114
|
+
os.chdir(current_dir)
|
|
1115
|
+
self.message.setText('Close and restart Cellects to apply the settings reset')
|
|
1116
|
+
self.message.setStyleSheet("color: rgb(230, 145, 18)")
|
|
1117
|
+
|
|
1118
|
+
def cancel_is_clicked(self):
|
|
1119
|
+
self.automatically_crop.setChecked(self.parent().po.all['automatically_crop'])
|
|
1120
|
+
self.subtract_background.setChecked(self.parent().po.vars['subtract_background'])
|
|
1121
|
+
self.keep_cell_and_back_for_all_folders.setChecked(self.parent().po.all['keep_cell_and_back_for_all_folders'])
|
|
1122
|
+
self.correct_errors_around_initial.setChecked(self.parent().po.vars['correct_errors_around_initial'])
|
|
1123
|
+
self.prevent_fast_growth_near_periphery.setChecked(self.parent().po.vars['prevent_fast_growth_near_periphery'])
|
|
1124
|
+
self.periphery_width.setValue(self.parent().po.vars['periphery_width'])
|
|
1125
|
+
self.max_periphery_growth.setValue(self.parent().po.vars['max_periphery_growth'])
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
self.first_move_threshold.setValue(self.parent().po.all['first_move_threshold_in_mm²'])
|
|
1129
|
+
self.pixels_to_mm.setChecked(self.parent().po.vars['output_in_mm'])
|
|
1130
|
+
self.do_automatic_size_thresholding.setChecked(self.parent().po.all['automatic_size_thresholding'])
|
|
1131
|
+
self.appearing_selection.setCurrentText(self.parent().po.vars['appearance_detection_method'])
|
|
1132
|
+
self.oscillation_period.setValue(self.parent().po.vars['expected_oscillation_period'])
|
|
1133
|
+
self.minimal_oscillating_cluster_size.setValue(self.parent().po.vars['minimal_oscillating_cluster_size'])
|
|
1134
|
+
|
|
1135
|
+
self.network_detection_threshold.setValue(self.parent().po.vars['network_detection_threshold'])
|
|
1136
|
+
|
|
1137
|
+
self.do_multiprocessing.setChecked(self.parent().po.all['do_multiprocessing'])
|
|
1138
|
+
self.max_core_nb.setValue(self.parent().po.all['cores'])
|
|
1139
|
+
self.min_memory_left.setValue(self.parent().po.vars['min_ram_free'])
|
|
1140
|
+
self.lose_accuracy_to_save_memory.setChecked(self.parent().po.vars['lose_accuracy_to_save_memory'])
|
|
1141
|
+
self.video_fps.setValue(self.parent().po.vars['video_fps'])
|
|
1142
|
+
self.keep_unaltered_videos.setChecked(self.parent().po.vars['keep_unaltered_videos'])
|
|
1143
|
+
self.save_processed_videos.setChecked(self.parent().po.vars['save_processed_videos'])
|
|
1144
|
+
self.time_step.setValue(self.parent().po.vars['time_step'])
|
|
1145
|
+
# self.parent().po.all['overwrite_cellects_data'] = self.overwrite_cellects_data.isChecked()
|
|
1146
|
+
|
|
1147
|
+
self.connect_distant_shape_during_segmentation.setChecked(self.parent().po.all['connect_distant_shape_during_segmentation'])
|
|
1148
|
+
do_use_max_size = self.parent().po.vars['max_size_for_connection'] is not None and self.parent().po.all['connect_distant_shape_during_segmentation']
|
|
1149
|
+
do_use_min_size = self.parent().po.vars['min_size_for_connection'] is not None and self.parent().po.all['connect_distant_shape_during_segmentation']
|
|
1150
|
+
self.use_max_size.setChecked(do_use_max_size)
|
|
1151
|
+
self.use_min_size.setChecked(do_use_min_size)
|
|
1152
|
+
if do_use_max_size:
|
|
1153
|
+
self.max_size_for_connection.setValue(self.parent().po.vars['max_size_for_connection'])
|
|
1154
|
+
else:
|
|
1155
|
+
self.max_size_for_connection.setValue(50)
|
|
1156
|
+
if do_use_min_size:
|
|
1157
|
+
self.min_size_for_connection.setValue(self.parent().po.vars['min_size_for_connection'])
|
|
1158
|
+
else:
|
|
1159
|
+
self.min_size_for_connection.setValue(0)
|
|
1160
|
+
|
|
1161
|
+
self.detection_range_factor.setValue(self.parent().po.vars['detection_range_factor'])
|
|
1162
|
+
self.all_specimens_have_same_direction.setChecked(self.parent().po.all['all_specimens_have_same_direction'])
|
|
1163
|
+
self.update_csc_editing_display()
|
|
1164
|
+
|
|
1165
|
+
if self.parent().last_is_first:
|
|
1166
|
+
self.parent().change_widget(0) # FirstWidget
|
|
1167
|
+
else:
|
|
1168
|
+
self.parent().change_widget(3) # ImageAnalysisWindow ThirdWidget
|
|
1169
|
+
|
|
1170
|
+
def ok_is_clicked(self):
|
|
1171
|
+
""" Triggered when ok is clicked, save the directory all_vars.pkl and go back to the previous window"""
|
|
1172
|
+
# if self.mesh_side_length.value() <= self.mesh_step_length.value():
|
|
1173
|
+
# self.message.setText('The mesh side has to be inferior to the mesh step')
|
|
1174
|
+
# self.message.setStyleSheet("color: rgb(230, 145, 18)")
|
|
1175
|
+
# else:
|
|
1176
|
+
self.parent().po.all['automatically_crop'] = self.automatically_crop.isChecked()
|
|
1177
|
+
self.parent().po.vars['subtract_background'] = self.subtract_background.isChecked()
|
|
1178
|
+
self.parent().po.all['keep_cell_and_back_for_all_folders'] = self.keep_cell_and_back_for_all_folders.isChecked()
|
|
1179
|
+
self.parent().po.vars['correct_errors_around_initial'] = self.correct_errors_around_initial.isChecked()
|
|
1180
|
+
self.parent().po.vars['prevent_fast_growth_near_periphery'] = self.prevent_fast_growth_near_periphery.isChecked()
|
|
1181
|
+
self.parent().po.vars['periphery_width'] = int(self.periphery_width.value())
|
|
1182
|
+
self.parent().po.vars['max_periphery_growth'] = int(self.max_periphery_growth.value())
|
|
1183
|
+
|
|
1184
|
+
# if self.parent().po.vars['origin_state'] == "invisible":
|
|
1185
|
+
self.parent().po.all['first_move_threshold_in_mm²'] = self.first_move_threshold.value()
|
|
1186
|
+
self.parent().po.vars['output_in_mm'] = self.pixels_to_mm.isChecked()
|
|
1187
|
+
self.parent().po.all['automatic_size_thresholding'] = self.do_automatic_size_thresholding.isChecked()
|
|
1188
|
+
self.parent().po.vars['appearance_detection_method'] = self.appearing_selection.currentText()
|
|
1189
|
+
self.parent().po.vars['expected_oscillation_period'] = self.oscillation_period.value()
|
|
1190
|
+
self.parent().po.vars['minimal_oscillating_cluster_size'] = int(self.minimal_oscillating_cluster_size.value())
|
|
1191
|
+
|
|
1192
|
+
self.parent().po.vars['network_detection_threshold'] = int(np.round(self.network_detection_threshold.value()))
|
|
1193
|
+
|
|
1194
|
+
self.parent().po.all['do_multiprocessing'] = self.do_multiprocessing.isChecked()
|
|
1195
|
+
self.parent().po.all['cores'] = np.uint8(self.max_core_nb.value())
|
|
1196
|
+
self.parent().po.vars['min_ram_free'] = self.min_memory_left.value()
|
|
1197
|
+
self.parent().po.vars['lose_accuracy_to_save_memory'] = self.lose_accuracy_to_save_memory.isChecked()
|
|
1198
|
+
self.parent().po.vars['video_fps'] = float(self.video_fps.value())
|
|
1199
|
+
self.parent().po.vars['keep_unaltered_videos'] = self.keep_unaltered_videos.isChecked()
|
|
1200
|
+
self.parent().po.vars['save_processed_videos'] = self.save_processed_videos.isChecked()
|
|
1201
|
+
self.parent().po.all['extract_time_interval'] = self.extract_time.isChecked()
|
|
1202
|
+
self.parent().po.vars['time_step'] = float(self.time_step.value())
|
|
1203
|
+
|
|
1204
|
+
do_distant_shape_int = self.connect_distant_shape_during_segmentation.isChecked()
|
|
1205
|
+
self.parent().po.all['connect_distant_shape_during_segmentation'] = do_distant_shape_int
|
|
1206
|
+
if do_distant_shape_int:
|
|
1207
|
+
self.parent().po.vars['detection_range_factor'] = int(
|
|
1208
|
+
np.round(self.detection_range_factor.value()))
|
|
1209
|
+
else:
|
|
1210
|
+
self.parent().po.vars['detection_range_factor'] = 0
|
|
1211
|
+
if self.use_max_size.isChecked():
|
|
1212
|
+
self.parent().po.vars['max_size_for_connection'] = int(np.round(self.max_size_for_connection.value()))
|
|
1213
|
+
else:
|
|
1214
|
+
self.parent().po.vars['max_size_for_connection'] = None
|
|
1215
|
+
if self.use_min_size.isChecked():
|
|
1216
|
+
self.parent().po.vars['min_size_for_connection'] = int(np.round(self.min_size_for_connection.value()))
|
|
1217
|
+
else:
|
|
1218
|
+
self.parent().po.vars['min_size_for_connection'] = None
|
|
1219
|
+
|
|
1220
|
+
self.parent().po.all['all_specimens_have_same_direction'] = self.all_specimens_have_same_direction.isChecked()
|
|
1221
|
+
|
|
1222
|
+
previous_csc = deepcopy(self.parent().po.vars['convert_for_motion'])
|
|
1223
|
+
self.save_user_defined_csc()
|
|
1224
|
+
print(self.parent().po.vars['convert_for_motion'])
|
|
1225
|
+
if self.parent().po.first_exp_ready_to_run:
|
|
1226
|
+
are_dicts_equal: bool = True
|
|
1227
|
+
for key in previous_csc.keys():
|
|
1228
|
+
if key != 'logical':
|
|
1229
|
+
are_dicts_equal = are_dicts_equal and np.all(key in self.parent().po.vars['convert_for_motion'] and previous_csc[key] == self.parent().po.vars['convert_for_motion'][key])
|
|
1230
|
+
for key in self.parent().po.vars['convert_for_motion'].keys():
|
|
1231
|
+
if key != 'logical':
|
|
1232
|
+
are_dicts_equal = are_dicts_equal and np.all(
|
|
1233
|
+
key in previous_csc and self.parent().po.vars['convert_for_motion'][key] ==
|
|
1234
|
+
previous_csc[key])
|
|
1235
|
+
if not are_dicts_equal:
|
|
1236
|
+
self.parent().po.find_if_lighter_background()
|
|
1237
|
+
|
|
1238
|
+
if not self.parent().thread['SaveAllVars'].isRunning():
|
|
1239
|
+
self.parent().thread['SaveAllVars'].start()
|
|
1240
|
+
|
|
1241
|
+
if self.parent().last_is_first:
|
|
1242
|
+
self.parent().change_widget(0) # FirstWidget
|
|
1243
|
+
else:
|
|
1244
|
+
self.parent().change_widget(3) # ImageAnalysisWindow ThirdWidget
|
|
1245
|
+
|
|
1246
|
+
def closeEvent(self, event):
|
|
1247
|
+
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())
|