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.
Files changed (38) hide show
  1. cellects/__main__.py +65 -25
  2. cellects/config/all_vars_dict.py +18 -17
  3. cellects/core/cellects_threads.py +1034 -396
  4. cellects/core/motion_analysis.py +1664 -2010
  5. cellects/core/one_image_analysis.py +1082 -1061
  6. cellects/core/program_organizer.py +1687 -1316
  7. cellects/core/script_based_run.py +80 -76
  8. cellects/gui/advanced_parameters.py +390 -330
  9. cellects/gui/cellects.py +102 -91
  10. cellects/gui/custom_widgets.py +16 -33
  11. cellects/gui/first_window.py +226 -104
  12. cellects/gui/if_several_folders_window.py +117 -68
  13. cellects/gui/image_analysis_window.py +866 -454
  14. cellects/gui/required_output.py +104 -57
  15. cellects/gui/ui_strings.py +840 -0
  16. cellects/gui/video_analysis_window.py +333 -155
  17. cellects/image_analysis/cell_leaving_detection.py +64 -4
  18. cellects/image_analysis/image_segmentation.py +451 -22
  19. cellects/image_analysis/morphological_operations.py +2166 -1635
  20. cellects/image_analysis/network_functions.py +616 -253
  21. cellects/image_analysis/one_image_analysis_threads.py +94 -153
  22. cellects/image_analysis/oscillations_functions.py +131 -0
  23. cellects/image_analysis/progressively_add_distant_shapes.py +2 -3
  24. cellects/image_analysis/shape_descriptors.py +517 -466
  25. cellects/utils/formulas.py +169 -6
  26. cellects/utils/load_display_save.py +362 -109
  27. cellects/utils/utilitarian.py +86 -9
  28. cellects-0.2.6.dist-info/LICENSE +675 -0
  29. cellects-0.2.6.dist-info/METADATA +829 -0
  30. cellects-0.2.6.dist-info/RECORD +44 -0
  31. cellects/core/one_video_per_blob.py +0 -540
  32. cellects/image_analysis/cluster_flux_study.py +0 -102
  33. cellects-0.1.2.dist-info/LICENSE.odt +0 -0
  34. cellects-0.1.2.dist-info/METADATA +0 -132
  35. cellects-0.1.2.dist-info/RECORD +0 -44
  36. {cellects-0.1.2.dist-info → cellects-0.2.6.dist-info}/WHEEL +0 -0
  37. {cellects-0.1.2.dist-info → cellects-0.2.6.dist-info}/entry_points.txt +0 -0
  38. {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
- """This module creates the Advanced Parameters window of the user interface of Cellects
3
- This windows contains most parameters
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() # QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
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)#self.parent().im_max_height - 100
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('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'])
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('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'])
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('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)",
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('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",
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('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)",
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('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",
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('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",
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
- # 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%;")
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("margin-left:100%; margin-right:0%;")
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('Automatic size threshold for appearance/motion',
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('Appearance detection method',
278
- tip="When specimen(s) are invisible at the beginning of the experiment and appear progressively",
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
- # IV/ Fourth box: Oscillation period:#
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('Expected oscillation period (min)',
313
- tip="If one expect biotic oscillations to occur",
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('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.",
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
- # self.layout.addWidget(self.scale_box_label, curr_row_2nd_col, 4)
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('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_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('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
-
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('Minimal RAM let free (Go)', night_mode=self.parent().po.all['night_mode'])
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('Lose accuracy to save RAM',
496
- tip="Use 8 bits instead of 64 to study each pixel",
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
- # self.layout.addWidget(self.video_saving_label, curr_row_2nd_col, 4)
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('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'])
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('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'])
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('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
+ 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('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'])
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
- """ Triggered when do_automatic_size_thresholding check status changes"""
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
- """ Triggered when connect_distant_shape_during_segmentation check status changes"""
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
- """ Triggered when use_max_size check status changes"""
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
- """ Triggered when use_min_size check status changes"""
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
- # self.edit_layout = QtWidgets.QGridLayout()
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
- # 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="",
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
- # self.logical_operator_between_combination_result.cha
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("margin-left:0%; margin-right:-10%;")
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("Heterogeneous back",
845
- tip="The program will split the image into categories", night_mode=self.parent().po.all['night_mode'])
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
- 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
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
- 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)
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
- """ 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:
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())