cellects 0.1.3__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 +365 -326
  9. cellects/gui/cellects.py +102 -91
  10. cellects/gui/custom_widgets.py +4 -3
  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 +841 -450
  14. cellects/gui/required_output.py +100 -56
  15. cellects/gui/ui_strings.py +840 -0
  16. cellects/gui/video_analysis_window.py +317 -135
  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 -105
  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.3.dist-info/LICENSE.odt +0 -0
  34. cellects-0.1.3.dist-info/METADATA +0 -176
  35. cellects-0.1.3.dist-info/RECORD +0 -44
  36. {cellects-0.1.3.dist-info → cellects-0.2.6.dist-info}/WHEEL +0 -0
  37. {cellects-0.1.3.dist-info → cellects-0.2.6.dist-info}/entry_points.txt +0 -0
  38. {cellects-0.1.3.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,18 +237,6 @@ 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
240
 
217
241
  self.use_min_size.setStyleSheet("QCheckBox::indicator {width: 12px;height: 12px;background-color: transparent;"
218
242
  "border-radius: 5px;border-style: solid;border-width: 1px;"
@@ -259,8 +283,6 @@ class AdvancedParameters(WindowType):
259
283
 
260
284
  self.one_per_arena_box_widget.setLayout(self.one_per_arena_box_layout)
261
285
  self.left_col_layout.addWidget(self.one_per_arena_box_widget)
262
- # self.layout.addWidget(self.one_per_arena_box_widget, curr_row_1st_col, 1, 3, 2)
263
- # curr_row_1st_col += 2# curr_box_row
264
286
 
265
287
  # III/ Third box: Appearing cell/colony
266
288
  # III/A/ Title
@@ -268,8 +290,6 @@ class AdvancedParameters(WindowType):
268
290
  night_mode=self.parent().po.all['night_mode'])
269
291
 
270
292
  self.left_col_layout.addWidget(self.appearing_cell_label)
271
- # self.layout.addWidget(self.appearing_cell_label, curr_row_1st_col, 1)
272
- # curr_row_1st_col += 1
273
293
  # III/B/ Create the box
274
294
  self.appearing_cell_box_layout = QtWidgets.QGridLayout()
275
295
  self.appearing_cell_box_widget = QtWidgets.QWidget()
@@ -281,15 +301,14 @@ class AdvancedParameters(WindowType):
281
301
  self.first_move_threshold_label = FixedText('Minimal size to detect a cell/colony',
282
302
  tip="In mm². All appearing cell/colony lesser than this value will be considered as noise",
283
303
  night_mode=self.parent().po.all['night_mode'])
284
- # self.first_move_threshold.setVisible(not self.parent().po.all['automatic_size_thresholding'])
285
- # self.first_move_threshold_label.setVisible(not self.parent().po.all['automatic_size_thresholding'])
286
304
  self.do_automatic_size_thresholding = Checkbox(self.parent().po.all['automatic_size_thresholding'])
287
- 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"],
288
307
  night_mode=self.parent().po.all['night_mode'])
289
308
  self.do_automatic_size_thresholding.stateChanged.connect(self.do_automatic_size_thresholding_changed)
290
309
  self.appearing_selection = Combobox(["largest", "most_central"], night_mode=self.parent().po.all['night_mode'])
291
- self.appearing_selection_label = FixedText('Appearance detection method',
292
- 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"],
293
312
  night_mode=self.parent().po.all['night_mode'])
294
313
  self.appearing_selection.setCurrentText(self.parent().po.vars['appearance_detection_method'])
295
314
  self.appearing_selection.setFixedWidth(190)
@@ -308,10 +327,70 @@ class AdvancedParameters(WindowType):
308
327
 
309
328
  self.appearing_cell_box_widget.setLayout(self.appearing_cell_box_layout)
310
329
  self.left_col_layout.addWidget(self.appearing_cell_box_widget)
311
- # self.layout.addWidget(self.appearing_cell_box_widget, curr_row_1st_col, 1, 2, 2)
312
- # curr_row_1st_col += curr_box_row
313
330
 
314
- # 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:
315
394
  # IV/A/ Title
316
395
  self.oscillation_label = FixedText('Oscillatory parameters:', tip="",
317
396
  night_mode=self.parent().po.all['night_mode'])
@@ -323,14 +402,14 @@ class AdvancedParameters(WindowType):
323
402
 
324
403
  self.oscillation_period = Spinbox(min=0, max=10000, val=self.parent().po.vars['expected_oscillation_period'], decimals=2,
325
404
  night_mode=self.parent().po.all['night_mode'])
326
- self.oscillation_period_label = FixedText('Expected oscillation period (min)',
327
- 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"],
328
407
  night_mode=self.parent().po.all['night_mode'])
329
408
 
330
409
  self.minimal_oscillating_cluster_size = Spinbox(min=1, max=1000000000, decimals=0, val=self.parent().po.vars['minimal_oscillating_cluster_size'],
331
410
  night_mode=self.parent().po.all['night_mode'])
332
- self.minimal_oscillating_cluster_size_label = FixedText('Minimal oscillating cluster size',
333
- 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"],
334
413
  night_mode=self.parent().po.all['night_mode'])
335
414
 
336
415
  self.oscillation_period_layout.addWidget(self.oscillation_period, 0, 0)
@@ -341,109 +420,27 @@ class AdvancedParameters(WindowType):
341
420
  self.oscillation_period_widget.setLayout(self.oscillation_period_layout)
342
421
  self.left_col_layout.addWidget(self.oscillation_period_widget)
343
422
 
344
-
345
- # V/ Fifth box: Fractal parameters:#
346
- # IV/A/ Title
347
- # self.fractal_label = FixedText('Fractal parameters:', tip="",
348
- # night_mode=self.parent().po.all['night_mode'])
349
- # self.left_col_layout.addWidget(self.fractal_label)
350
- #
351
- # self.fractal_layout = QtWidgets.QGridLayout()
352
- # self.fractal_widget = QtWidgets.QWidget()
353
- # self.fractal_widget.setStyleSheet(boxstylesheet)
354
- #
355
- # self.fractal_box_side_threshold = Spinbox(min=0, max=100000, val=self.parent().po.vars['fractal_box_side_threshold'], decimals=0,
356
- # night_mode=self.parent().po.all['night_mode'])
357
- # self.fractal_box_side_threshold_label = FixedText('Fractal box side threshold',
358
- # tip="Increase/decrease to adjust the minimal side length (pixels) of an image\nto compute the Minkowski dimension using the box counting method.",
359
- # night_mode=self.parent().po.all['night_mode'])
360
- # self.fractal_layout.addWidget(self.fractal_box_side_threshold, 3, 0)
361
- # self.fractal_layout.addWidget(self.fractal_box_side_threshold_label, 3, 1)
362
- # self.fractal_zoom_step = Spinbox(min=0, max=100000, val=self.parent().po.vars['fractal_zoom_step'], decimals=0,
363
- # night_mode=self.parent().po.all['night_mode'])
364
- # self.fractal_zoom_step_label = FixedText('Fractal zoom step',
365
- # 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.",
366
- # night_mode=self.parent().po.all['night_mode'])
367
- # self.fractal_layout.addWidget(self.fractal_zoom_step, 4, 0)
368
- # self.fractal_layout.addWidget(self.fractal_zoom_step_label, 4, 1)
369
- #
370
- # self.fractal_widget.setLayout(self.fractal_layout)
371
- # self.left_col_layout.addWidget(self.fractal_widget)
372
-
373
- # V/ Fifth box: Network detection parameters:#
374
- # IV/A/ Title
375
- self.network_label = FixedText('Network parameters:', tip="",
376
- night_mode=self.parent().po.all['night_mode'])
377
- self.left_col_layout.addWidget(self.network_label)
378
-
379
- self.network_layout = QtWidgets.QGridLayout()
380
- self.network_widget = QtWidgets.QWidget()
381
- self.network_widget.setStyleSheet(boxstylesheet)
382
-
383
-
384
- self.network_detection_threshold = Spinbox(min=0, max=255, val=self.parent().po.vars['network_detection_threshold'], decimals=0,
385
- night_mode=self.parent().po.all['night_mode'])
386
- self.network_detection_threshold_label = FixedText('Network detection threshold',
387
- 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.",
388
- night_mode=self.parent().po.all['night_mode'])
389
- # self.mesh_side_length = Spinbox(min=2, max=1000000, val=self.parent().po.vars['network_mesh_side_length'], decimals=0,
390
- # night_mode=self.parent().po.all['night_mode'])
391
- # self.mesh_side_length_label = FixedText('Mesh side length',
392
- # 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.",
393
- # night_mode=self.parent().po.all['night_mode'])
394
- # self.mesh_step_length = Spinbox(min=1, max=100, val=self.parent().po.vars['network_mesh_step_length'], decimals=0,
395
- # night_mode=self.parent().po.all['night_mode'])
396
- # self.mesh_step_length_label = FixedText('Mesh step length',
397
- # 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.",
398
- # night_mode=self.parent().po.all['night_mode'])
399
-
400
- self.network_layout.addWidget(self.network_detection_threshold, 0, 0)
401
- self.network_layout.addWidget(self.network_detection_threshold_label, 0, 1)
402
- # self.network_layout.addWidget(self.mesh_side_length, 1, 0)
403
- # self.network_layout.addWidget(self.mesh_side_length_label, 1, 1)
404
- # self.network_layout.addWidget(self.mesh_step_length, 2, 0)
405
- # self.network_layout.addWidget(self.mesh_step_length_label, 2, 1)
406
-
407
- self.network_widget.setLayout(self.network_layout)
408
- self.left_col_layout.addWidget(self.network_widget)
409
-
410
-
411
- # self.layout.addWidget(self.oscillation_period_widget, curr_row_1st_col, 1)
412
- # curr_row_1st_col + 1
413
-
414
-
415
- # From here start the 2nd column of boxes in the advanced parameters window
416
- # vertspaceItem = QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding,
417
- # QtWidgets.QSizePolicy.Maximum)
418
- # self.layout.addItem(vertspaceItem, 0, 3, 10, 1)
419
- # curr_row_2nd_col = 3
420
-
421
-
422
423
  # I/ First box: Scales
423
424
  # I/A/ Title
424
-
425
- 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
426
426
  self.right_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
427
427
  self.right_scroll_table.setMinimumHeight(150)#self.parent().im_max_height - 100
428
428
  self.right_scroll_table.setFrameShape(QtWidgets.QFrame.NoFrame)
429
429
  self.right_scroll_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
430
430
  self.right_scroll_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
431
-
432
-
433
- 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"],
434
433
  night_mode=self.parent().po.all['night_mode'])
435
434
  self.right_col_layout.addWidget(self.scale_box_label)
436
- # self.layout.addWidget(self.scale_box_label, curr_row_2nd_col, 4)
437
- # curr_row_2nd_col += 1
435
+
438
436
  # I/B/ Create the box
439
437
  self.scale_box_layout = QtWidgets.QGridLayout()
440
438
  self.scale_box_widget = QtWidgets.QWidget()
441
439
  self.scale_box_widget.setStyleSheet(boxstylesheet)
442
- # I/C/ Create widgets
443
440
 
441
+ # I/C/ Create widgets
444
442
  self.extract_time = Checkbox(self.parent().po.all['extract_time_interval'])
445
443
  self.extract_time.clicked.connect(self.extract_time_is_clicked)
446
-
447
444
  self.time_step = Spinbox(min=0, max=100000, val=self.parent().po.vars['time_step'], decimals=3,
448
445
  night_mode=self.parent().po.all['night_mode'])
449
446
  self.time_step.setFixedWidth(60)
@@ -456,35 +453,25 @@ class AdvancedParameters(WindowType):
456
453
  self.time_step_label = FixedText('Set the time interval between images',
457
454
  tip="In minutes",
458
455
  night_mode=self.parent().po.all['night_mode'])
459
- # self.overwrite_cellects_data = Checkbox(self.parent().po.all['overwrite_cellects_data'],
460
- # night_mode=self.parent().po.all['night_mode'])
461
- # self.overwrite_cellects_data_label = FixedText('Do overwrite cellects data',
462
- # tip="The file Data to run Cellects quickly.pkl allow to run\na complete analysis from the first and the video anaysis window",
463
- # night_mode=self.parent().po.all['night_mode'])
464
456
  self.pixels_to_mm = Checkbox(self.parent().po.vars['output_in_mm'])
465
457
  self.pixels_to_mm_label = FixedText('Convert areas and distances from pixels to mm',
466
458
  tip="Check if you want output variables to be in mm\nUncheck if you want output variables to be in pixels",
467
459
  night_mode=self.parent().po.all['night_mode'])
460
+
468
461
  # I/D/ Arrange widgets in the box
469
462
  self.scale_box_layout.addWidget(self.extract_time, 0, 0)
470
463
  self.scale_box_layout.addWidget(self.time_step_label, 0, 1)
471
464
  self.scale_box_layout.addWidget(self.time_step, 0, 2)
472
- # self.scale_box_layout.addWidget(self.overwrite_cellects_data, 1, 0)
473
- # self.scale_box_layout.addWidget(self.overwrite_cellects_data_label, 1, 1)
474
465
  self.scale_box_layout.addWidget(self.pixels_to_mm, 2, 0)
475
466
  self.scale_box_layout.addWidget(self.pixels_to_mm_label, 2, 1)
476
467
  self.scale_box_widget.setLayout(self.scale_box_layout)
477
468
  self.right_col_layout.addWidget(self.scale_box_widget)
478
- # self.layout.addWidget(self.scale_box_widget, curr_row_2nd_col, 4, 2, 2)
479
- # curr_row_2nd_col += 3
480
469
 
481
470
  # IV/ Fourth box: Computer resources
482
471
  # IV/A/ Title
483
472
  self.resources_label = FixedText('Computer resources:', tip="",
484
473
  night_mode=self.parent().po.all['night_mode'])
485
474
  self.right_col_layout.addWidget(self.resources_label)
486
- # self.layout.addWidget(self.resources_label, curr_row_2nd_col, 4)
487
- # curr_row_2nd_col += 1
488
475
 
489
476
  # IV/B/ Create the box
490
477
  self.resources_box_layout = QtWidgets.QGridLayout()
@@ -493,21 +480,23 @@ class AdvancedParameters(WindowType):
493
480
 
494
481
  # IV/C/ Create widgets
495
482
  self.do_multiprocessing = Checkbox(self.parent().po.all['do_multiprocessing'])
496
- 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'])
497
485
  self.do_multiprocessing.stateChanged.connect(self.do_multiprocessing_is_clicked)
498
486
  self.max_core_nb = Spinbox(min=0, max=256, val=self.parent().po.all['cores'],
499
487
  night_mode=self.parent().po.all['night_mode'])
500
- self.max_core_nb_label = FixedText('Proc max core number', night_mode=self.parent().po.all['night_mode'])
501
- # self.max_core_nb.setVisible(self.parent().po.all['do_multiprocessing'])
502
- # self.max_core_nb_label.setVisible(self.parent().po.all['do_multiprocessing'])
503
-
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'])
504
491
  self.min_memory_left = Spinbox(min=0, max=1024, val=self.parent().po.vars['min_ram_free'], decimals=1,
505
492
  night_mode=self.parent().po.all['night_mode'])
506
- 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'])
507
496
 
508
497
  self.lose_accuracy_to_save_memory = Checkbox(self.parent().po.vars['lose_accuracy_to_save_memory'])
509
- self.lose_accuracy_to_save_memory_label = FixedText('Lose accuracy to save RAM',
510
- 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"],
511
500
  night_mode=self.parent().po.all['night_mode'])
512
501
 
513
502
  # IV/D/ Arrange widgets in the box
@@ -521,16 +510,13 @@ class AdvancedParameters(WindowType):
521
510
  self.resources_box_layout.addWidget(self.lose_accuracy_to_save_memory_label, 3, 1)
522
511
  self.resources_box_widget.setLayout(self.resources_box_layout)
523
512
  self.right_col_layout.addWidget(self.resources_box_widget)
524
- # self.layout.addWidget(self.resources_box_widget, curr_row_2nd_col, 4, 2, 2)
525
- # curr_row_2nd_col += 3
526
513
 
527
514
  # V/ Fifth box: Video saving
528
515
  # V/A/ Title
529
516
  self.video_saving_label = FixedText('Video saving:', tip="",
530
517
  night_mode=self.parent().po.all['night_mode'])
531
518
  self.right_col_layout.addWidget(self.video_saving_label)
532
- # self.layout.addWidget(self.video_saving_label, curr_row_2nd_col, 4)
533
- # curr_row_2nd_col += 1
519
+
534
520
  # V/B/ Create the box
535
521
  self.video_saving_layout = QtWidgets.QGridLayout()
536
522
  self.video_saving_widget = QtWidgets.QWidget()
@@ -539,82 +525,67 @@ class AdvancedParameters(WindowType):
539
525
  # V/C/ Create widgets
540
526
  self.video_fps = Spinbox(min=0, max=10000, val=self.parent().po.vars['video_fps'], decimals=2,
541
527
  night_mode=self.parent().po.all['night_mode'])
542
- self.video_fps_label = FixedText('Video fps', night_mode=self.parent().po.all['night_mode'])
543
- # self.overwrite_unaltered_videos = Checkbox(self.parent().po.all['overwrite_unaltered_videos'])
544
- # 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'])
545
530
  self.keep_unaltered_videos = Checkbox(self.parent().po.vars['keep_unaltered_videos'])
546
- 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'])
547
534
  self.save_processed_videos = Checkbox(self.parent().po.vars['save_processed_videos'])
548
- 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'])
549
538
 
550
539
  # V/D/ Arrange widgets in the box
551
540
  curr_box_row = 0
552
541
  self.video_saving_layout.addWidget(self.video_fps, curr_box_row, 0)
553
542
  self.video_saving_layout.addWidget(self.video_fps_label, curr_box_row, 1)
554
543
  curr_box_row += 1
555
- # self.video_saving_layout.addWidget(self.overwrite_unaltered_videos, curr_box_row, 0)
556
- # self.video_saving_layout.addWidget(self.overwrite_unaltered_videos_label, curr_box_row, 1)
557
- # curr_box_row += 1
558
544
  self.video_saving_layout.addWidget(self.keep_unaltered_videos, curr_box_row, 0)
559
545
  self.video_saving_layout.addWidget(self.keep_unaltered_videos_label, curr_box_row, 1)
560
546
  curr_box_row += 1
561
547
  self.video_saving_layout.addWidget(self.save_processed_videos, curr_box_row, 0)
562
548
  self.video_saving_layout.addWidget(self.save_processed_videos_label, curr_box_row, 1)
563
549
  curr_box_row += 1
564
-
565
550
  self.video_saving_widget.setLayout(self.video_saving_layout)
566
551
  self.right_col_layout.addWidget(self.video_saving_widget)
567
- # self.layout.addWidget(self.video_saving_widget, curr_row_2nd_col, 4, 2, 2)
568
- # curr_row_2nd_col += 2
569
552
 
570
553
  # VII/ Seventh box: csc
571
554
  # VII/A/ Title
572
- # self.video_csc_label = FixedText('Color space combination for video analysis:', tip="",
573
- # night_mode=self.parent().po.all['night_mode'])
574
- # self.right_col_layout.addWidget(self.video_csc_label)
575
- # self.layout.addWidget(self.video_csc_label, curr_row_2nd_col, 4)
576
- # curr_row_2nd_col += 1
577
-
578
555
  # VII/C/ Create widgets
579
556
  self.generate_csc_editing()
580
557
  # VII/D/ Arrange widgets in the box
581
558
  self.right_col_layout.addWidget(self.edit_widget)
582
- # self.layout.addWidget(self.edit_widget, curr_row_2nd_col, 4, 2, 2)
583
- # curr_row_2nd_col += 3
584
559
 
585
560
  # VIII/ Finalize layout and add the night mode option and the ok button
586
561
  self.left_col_layout.addItem(self.vertical_space)
587
562
  self.right_col_layout.addItem(self.vertical_space)
588
563
  self.left_col_widget.setLayout(self.left_col_layout)
589
-
590
-
591
564
  self.right_col_widget.setLayout(self.right_col_layout)
592
565
  self.central_layout = QtWidgets.QHBoxLayout()
593
566
  self.central_layout.addItem(self.horizontal_space)
594
- #self.central_layout.addWidget(self.left_col_widget)
595
-
596
567
  self.left_scroll_table.setWidget(self.left_col_widget)
597
568
  self.left_scroll_table.setWidgetResizable(True)
598
569
  self.central_layout.addWidget(self.left_scroll_table)
599
-
600
-
601
570
  self.central_layout.addItem(self.horizontal_space)
602
571
  self.right_scroll_table.setWidget(self.right_col_widget)
603
572
  self.right_scroll_table.setWidgetResizable(True)
604
573
  self.central_layout.addWidget(self.right_scroll_table)
605
- # self.central_layout.addWidget(self.right_col_widget)
606
574
  self.central_layout.addItem(self.horizontal_space)
607
575
  self.central_widget = QtWidgets.QWidget()
608
576
  self.central_widget.setLayout(self.central_layout)
609
577
  self.layout.addWidget(self.central_widget)
610
- self.layout.addItem(self.vertical_space)
578
+ # self.layout.addItem(self.vertical_space)
579
+
611
580
  # Last row
612
581
  self.last_row_layout = QtWidgets.QHBoxLayout()
613
582
  self.last_row_widget = QtWidgets.QWidget()
614
583
  self.night_mode_cb = Checkbox(self.parent().po.all['night_mode'])
615
584
  self.night_mode_cb.clicked.connect(self.night_mode_is_clicked)
616
- self.night_mode_label = FixedText('Night mode', night_mode=self.parent().po.all['night_mode'])
617
- 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'])
618
589
  self.reset_all_settings.clicked.connect(self.reset_all_settings_is_clicked)
619
590
  self.message = FixedText('', night_mode=self.parent().po.all['night_mode'])
620
591
  self.cancel = PButton('Cancel', night_mode=self.parent().po.all['night_mode'])
@@ -634,6 +605,13 @@ class AdvancedParameters(WindowType):
634
605
  self.setLayout(self.layout)
635
606
 
636
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
+ """
637
615
  self.max_core_nb.setVisible(self.parent().po.all['do_multiprocessing'])
638
616
  self.max_core_nb_label.setVisible(self.parent().po.all['do_multiprocessing'])
639
617
  self.first_move_threshold.setVisible(not self.parent().po.all['automatic_size_thresholding'])
@@ -663,11 +641,17 @@ class AdvancedParameters(WindowType):
663
641
  self.row21[3].setValue(0)
664
642
 
665
643
  def subtract_background_check(self):
644
+ """
645
+ Handles the logic for using background subtraction or not during image segmentation.
646
+ """
666
647
  self.parent().po.motion = None
667
648
  if self.subtract_background.isChecked():
668
649
  self.parent().po.first_exp_ready_to_run = False
669
650
 
670
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
+ """
671
655
  checked_status = self.prevent_fast_growth_near_periphery.isChecked()
672
656
  self.periphery_width.setVisible(checked_status)
673
657
  self.periphery_width_label.setVisible(checked_status)
@@ -675,11 +659,28 @@ class AdvancedParameters(WindowType):
675
659
  self.max_periphery_growth_label.setVisible(checked_status)
676
660
 
677
661
  def do_automatic_size_thresholding_changed(self):
678
- """ 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
+ """
679
667
  self.first_move_threshold.setVisible(not self.do_automatic_size_thresholding.isChecked())
680
668
  self.first_move_threshold_label.setVisible(not self.do_automatic_size_thresholding.isChecked())
681
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
+
682
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
+ """
683
684
  self.time_step.setVisible(not self.extract_time.isChecked())
684
685
  if self.extract_time.isChecked():
685
686
  self.time_step_label.setText("Automatically extract time interval between images")
@@ -689,15 +690,17 @@ class AdvancedParameters(WindowType):
689
690
  self.time_step_label.setToolTip("In minutes")
690
691
 
691
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
+ """
692
696
  self.max_core_nb.setVisible(self.do_multiprocessing.isChecked())
693
697
  self.max_core_nb_label.setVisible(self.do_multiprocessing.isChecked())
694
698
 
695
- # def all_specimens_have_same_direction_changed(self):
696
- # """ Triggered when all_specimens_have_same_direction check status changes"""
697
- # self.parent().po.all['all_specimens_have_same_direction'] = self.all_specimens_have_same_direction.isChecked()
698
-
699
699
  def do_distant_shape_int_changed(self):
700
- """ 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
+ """
701
704
  do_distant_shape_int = self.connect_distant_shape_during_segmentation.isChecked()
702
705
  self.detection_range_factor.setVisible(do_distant_shape_int)
703
706
  if do_distant_shape_int:
@@ -715,7 +718,9 @@ class AdvancedParameters(WindowType):
715
718
  self.min_size_for_connection_label.setVisible(do_use_min_size)
716
719
 
717
720
  def use_max_size_changed(self):
718
- """ Triggered when use_max_size check status changes"""
721
+ """
722
+ Toggles the visibility of max size input fields based on checkbox state.
723
+ """
719
724
  do_use_max_size = self.use_max_size.isChecked()
720
725
  self.max_size_for_connection.setVisible(do_use_max_size)
721
726
  self.max_size_for_connection_label.setVisible(do_use_max_size)
@@ -723,7 +728,9 @@ class AdvancedParameters(WindowType):
723
728
  self.max_size_for_connection.setValue(300)
724
729
 
725
730
  def use_min_size_changed(self):
726
- """ 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
+ """
727
734
  do_use_min_size = self.use_min_size.isChecked()
728
735
  self.min_size_for_connection.setVisible(do_use_min_size)
729
736
  self.min_size_for_connection_label.setVisible(do_use_min_size)
@@ -731,50 +738,26 @@ class AdvancedParameters(WindowType):
731
738
  self.min_size_for_connection.setValue(30)
732
739
 
733
740
  def generate_csc_editing(self):
734
- # 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
+ """
735
747
  self.edit_widget = QtWidgets.QWidget()
736
- # self.edit_widget.setVisible(False)
737
- # self.edit_widget.setStyleSheet(boxstylesheet)
738
748
  self.edit_layout = QtWidgets.QVBoxLayout()
739
-
740
- # self.csc_scroll_table = QtWidgets.QScrollArea() # QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
741
- # # self.csc_scroll_table.setVisible(False)
742
- # # self.csc_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
743
- # self.csc_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
744
- # self.csc_scroll_table.setMinimumHeight(150)#self.parent().im_max_height - 100
745
- # # self.csc_scroll_table.setMinimumWidth(300)
746
- # self.csc_scroll_table.setFrameShape(QtWidgets.QFrame.NoFrame)
747
- # self.csc_scroll_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
748
- # self.csc_scroll_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
749
749
  self.csc_table_widget = QtWidgets.QWidget()
750
750
  self.csc_table_layout = QtWidgets.QVBoxLayout()
751
751
 
752
752
  # 2) Titles
753
- # self.edit_labels_widget = QtWidgets.QWidget()
754
- # self.edit_labels_widget.setFixedHeight(50)
755
- # self.edit_labels_layout = QtWidgets.QHBoxLayout()
756
- # self.space_label = FixedText('Space', align='c',
757
- # 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",
758
- # night_mode=self.parent().po.all['night_mode'])
759
- # self.c1 = FixedText(' C1', align='c', tip="Increase if it increase cell detection", night_mode=self.parent().po.all['night_mode'])
760
- # self.c2 = FixedText(' C2', align='c', tip="Increase if it increase cell detection", night_mode=self.parent().po.all['night_mode'])
761
- # self.c3 = FixedText(' C3', align='c', tip="Increase if it increase cell detection", night_mode=self.parent().po.all['night_mode'])
762
- #
763
- # self.edit_labels_layout.addWidget(self.space_label)
764
- # self.edit_labels_layout.addWidget(self.c1)
765
- # self.edit_labels_layout.addWidget(self.c2)
766
- # self.edit_labels_layout.addWidget(self.c3)
767
- # self.edit_labels_layout.addItem(self.horizontal_space)
768
- # self.edit_labels_widget.setLayout(self.edit_labels_layout)
769
- # # self.edit_layout.addWidget(self.edit_labels_widget)
770
- # self.csc_table_layout.addWidget(self.edit_labels_widget)
771
- 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"],
772
755
  night_mode=self.parent().po.all['night_mode'])
773
756
  self.video_csc_label.setFixedHeight(30)
774
757
  self.csc_table_layout.addWidget(self.video_csc_label)
775
-
776
758
  self.both_csc_widget = QtWidgets.QWidget()
777
759
  self.both_csc_layout = QtWidgets.QHBoxLayout()
760
+
778
761
  # 3) First CSC
779
762
  self.first_csc_widget = QtWidgets.QWidget()
780
763
  self.first_csc_layout = QtWidgets.QGridLayout()
@@ -788,17 +771,13 @@ class AdvancedParameters(WindowType):
788
771
  self.logical_operator_between_combination_result.setCurrentText(self.parent().po.vars['convert_for_motion']['logical'])
789
772
  self.logical_operator_between_combination_result.currentTextChanged.connect(self.logical_op_changed)
790
773
  self.logical_operator_between_combination_result.setFixedWidth(100)
791
- # self.logical_operator_between_combination_result.cha
792
- 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"],
793
775
  night_mode=self.parent().po.all['night_mode'])
794
-
795
776
  self.row21 = self.one_csc_editing()
796
777
  self.row21[4].clicked.connect(self.display_row22)
797
778
  self.row22 = self.one_csc_editing()
798
779
  self.row22[4].clicked.connect(self.display_row23)
799
780
  self.row23 = self.one_csc_editing()
800
-
801
-
802
781
  for i in range(5):
803
782
  self.first_csc_layout.addWidget(self.row1[i], 0, i, 1, 1)
804
783
  self.first_csc_layout.addWidget(self.row2[i], 1, i, 1, 1)
@@ -810,9 +789,6 @@ class AdvancedParameters(WindowType):
810
789
  self.first_csc_layout.addItem(self.horizontal_space, 0, 5, 3, 1)
811
790
  self.first_csc_widget.setLayout(self.first_csc_layout)
812
791
  self.both_csc_layout.addWidget(self.first_csc_widget)
813
- # self.csc_table_layout.addWidget(self.first_csc_widget)
814
- # self.edit_layout.addWidget(self.first_csc_widget)
815
-
816
792
 
817
793
  # 5) Second CSC
818
794
  self.second_csc_widget = QtWidgets.QWidget()
@@ -831,8 +807,6 @@ class AdvancedParameters(WindowType):
831
807
  self.both_csc_layout.addWidget(self.second_csc_widget)
832
808
  self.both_csc_widget.setLayout(self.both_csc_layout)
833
809
  self.csc_table_layout.addWidget(self.both_csc_widget)
834
- # self.csc_table_layout.addWidget(self.second_csc_widget)
835
-
836
810
 
837
811
  # 4) logical_operator
838
812
  self.logical_op_widget = QtWidgets.QWidget()
@@ -846,7 +820,6 @@ class AdvancedParameters(WindowType):
846
820
  self.logical_op_widget.setLayout(self.logical_op_layout)
847
821
  self.logical_op_widget.setFixedHeight(50)
848
822
  self.csc_table_layout.addWidget(self.logical_op_widget)
849
- # self.edit_layout.addWidget(self.logical_op_widget)
850
823
 
851
824
  # 6) Open the more_than_2_colors row layout
852
825
  self.more_than_2_colors_widget = QtWidgets.QWidget()
@@ -862,17 +835,11 @@ class AdvancedParameters(WindowType):
862
835
  "QCheckBox:margin-right {-10%}")
863
836
  self.more_than_two_colors.stateChanged.connect(self.display_more_than_two_colors_option)
864
837
 
865
- self.more_than_two_colors_label = FixedText("Heterogeneous back",
866
- 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'])
867
840
  self.more_than_two_colors_label.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
868
- # self.more_than_two_colors_label.setFixedWidth(300)
869
841
  self.more_than_two_colors_label.setAlignment(QtCore.Qt.AlignLeft)
870
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'])
871
- # self.distinct_colors_number.valueChanged.connect(self.distinct_colors_number_changed)
872
- # self.display_more_than_two_colors_option()
873
- # self.more_than_two_colors.setVisible(False)
874
- # self.more_than_two_colors_label.setVisible(False)
875
- # self.distinct_colors_number.setVisible(False)
876
843
  self.more_than_2_colors_layout.addWidget(self.more_than_two_colors)
877
844
  self.more_than_2_colors_layout.addWidget(self.more_than_two_colors_label)
878
845
  self.more_than_2_colors_layout.addWidget(self.distinct_colors_number)
@@ -884,20 +851,24 @@ class AdvancedParameters(WindowType):
884
851
  self.csc_table_widget.setLayout(self.csc_table_layout)
885
852
 
886
853
  self.edit_layout.addWidget(self.csc_table_widget)
887
- # self.csc_scroll_table.setWidget(self.csc_table_widget)
888
- # self.csc_scroll_table.setWidgetResizable(True)
889
- # self.edit_layout.addWidget(self.csc_scroll_table)
890
-
891
- # self.more_than_2_colors_layout.addWidget(self.more_than_two_colors)
892
- # self.more_than_2_colors_layout.addWidget(self.more_than_two_colors_label)
893
- # self.more_than_2_colors_layout.addWidget(self.distinct_colors_number)
894
- # self.more_than_2_colors_layout.addItem(self.horizontal_space)
895
- # self.more_than_2_colors_widget.setLayout(self.more_than_2_colors_layout)
896
- # self.edit_layout.addWidget(self.more_than_2_colors_widget)
897
854
 
898
855
  self.edit_widget.setLayout(self.edit_layout)
899
856
 
900
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
+ """
901
872
  widget_list = []
902
873
  widget_list.insert(0, Combobox(["None", "bgr", "hsv", "hls", "lab", "luv", "yuv"],
903
874
  night_mode=self.parent().po.all['night_mode']))
@@ -911,6 +882,9 @@ class AdvancedParameters(WindowType):
911
882
  return widget_list
912
883
 
913
884
  def logical_op_changed(self):
885
+ """
886
+ Update the visibility and values of UI components based on the logical operator selection.
887
+ """
914
888
  # show = self.logical_operator_between_combination_result.currentText() != 'None'
915
889
  if self.logical_operator_between_combination_result.currentText() == 'None':
916
890
  self.row21[0].setVisible(False)
@@ -940,71 +914,100 @@ class AdvancedParameters(WindowType):
940
914
  self.row21[i1 + 1].setVisible(True)
941
915
 
942
916
  def display_logical_operator(self):
917
+ """
918
+ Display logical operator components in the user interface.
919
+ """
943
920
  self.logical_operator_between_combination_result.setVisible(True)
944
921
  self.logical_operator_label.setVisible(True)
945
922
 
946
923
  def display_row2(self):
924
+ """
925
+ Display or hide the second row of the csc editing widgets.
926
+ """
947
927
  self.row1[4].setVisible(False)
948
928
  for i in range(5):
949
929
  self.row2[i].setVisible(True)
950
930
  self.display_logical_operator()
951
931
 
952
932
  def display_row3(self):
933
+ """
934
+ Display or hide the third row of the csc editing widgets.
935
+ """
953
936
  self.row2[4].setVisible(False)
954
937
  for i in range(4):
955
938
  self.row3[i].setVisible(True)
956
939
  self.display_logical_operator()
957
940
 
958
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
+ """
959
945
  self.row21[4].setVisible(False)
960
946
  for i in range(5):
961
947
  self.row22[i].setVisible(True)
962
948
  self.display_logical_operator()
963
949
 
964
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
+ """
965
954
  self.row22[4].setVisible(False)
966
955
  for i in range(4):
967
956
  self.row23[i].setVisible(True)
968
957
  self.display_logical_operator()
969
958
 
970
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
+ """
971
968
  c_space_order = ["None", "bgr", "hsv", "hls", "lab", "luv", "yuv"]
972
969
  remaining_c_spaces = []
973
970
  row_number1 = 0
974
971
  row_number2 = 0
975
- for i, (k, v) in enumerate(self.parent().po.vars['convert_for_motion'].items()):
976
- if k != "logical":
977
- if k[-1] != "2":
978
- if row_number1 == 0:
979
- row_to_change = self.row1
980
- elif row_number1 == 1:
981
- row_to_change = self.row2
982
- elif row_number1 == 2:
983
- row_to_change = self.row3
984
- else:
985
- remaining_c_spaces.append(k + " " + str(v))
986
- row_number1 += 1
987
- current_row_number = row_number1
988
- else:
989
- if row_number2 == 0:
990
- row_to_change = self.row21
991
- elif row_number2 == 1:
992
- row_to_change = self.row22
993
- elif row_number2 == 2:
994
- 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
995
991
  else:
996
- remaining_c_spaces.append(k + " " + str(v))
997
- row_number2 += 1
998
- current_row_number = row_number2
999
- k = k[:-1]
1000
- if current_row_number <= 3:
1001
- row_to_change[0].setCurrentIndex(np.nonzero(np.isin(c_space_order, k))[0][0])
1002
- row_to_change[0].setVisible(True)
1003
- for i1, i2 in zip([1, 2, 3], [0, 1, 2]):
1004
- row_to_change[i1].setValue(v[i2])
1005
- row_to_change[i1].setVisible(True)
1006
- if current_row_number < 3:
1007
- 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)
1008
1011
 
1009
1012
  # If not all color space combinations are filled, put None and 0 in boxes
1010
1013
  if row_number1 < 3:
@@ -1058,6 +1061,9 @@ class AdvancedParameters(WindowType):
1058
1061
  self.row22[i1 + 1].setVisible(False)
1059
1062
 
1060
1063
  def save_user_defined_csc(self):
1064
+ """
1065
+ Save user-defined combination of color spaces and channels.
1066
+ """
1061
1067
  self.parent().po.vars['convert_for_motion'] = {}
1062
1068
  spaces = np.array((self.row1[0].currentText(), self.row2[0].currentText(), self.row3[0].currentText()))
1063
1069
  channels = np.array(
@@ -1082,6 +1088,8 @@ class AdvancedParameters(WindowType):
1082
1088
  if not np.all(spaces == "None"):
1083
1089
  for i, space in enumerate(spaces):
1084
1090
  if space != "None" and space != "None2":
1091
+ if np.any(channels[i, :] < 0.):
1092
+ channels[i, :] + channels[i, :].min()
1085
1093
  self.parent().po.vars['convert_for_motion'][space] = channels[i, :]
1086
1094
  if len(self.parent().po.vars['convert_for_motion']) == 1 or channels.sum() == 0:
1087
1095
  self.csc_dict_is_empty = True
@@ -1095,6 +1103,12 @@ class AdvancedParameters(WindowType):
1095
1103
  self.parent().videoanalysiswindow.select_option_label.setVisible(True)
1096
1104
 
1097
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
+ """
1098
1112
  if self.more_than_two_colors.isChecked():
1099
1113
  self.distinct_colors_number.setVisible(True)
1100
1114
  self.more_than_two_colors_label.setText("How many distinct colors?")
@@ -1104,12 +1118,6 @@ class AdvancedParameters(WindowType):
1104
1118
  self.distinct_colors_number.setVisible(False)
1105
1119
  self.distinct_colors_number.setValue(2)
1106
1120
 
1107
-
1108
- # self.parent().po.vars["color_number"] = 2
1109
-
1110
- # def distinct_colors_number_changed(self):
1111
- # self.parent().po.vars["color_number"] = int(self.distinct_colors_number.value())
1112
-
1113
1121
  def night_mode_is_clicked(self):
1114
1122
  """ Triggered when night_mode_cb check status changes"""
1115
1123
  self.parent().po.all['night_mode'] = self.night_mode_cb.isChecked()
@@ -1117,6 +1125,16 @@ class AdvancedParameters(WindowType):
1117
1125
  self.message.setStyleSheet("color: rgb(230, 145, 18)")
1118
1126
 
1119
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
+ """
1120
1138
  if os.path.isfile('Data to run Cellects quickly.pkl'):
1121
1139
  os.remove('Data to run Cellects quickly.pkl')
1122
1140
  if os.path.isfile('PickleRick.pkl'):
@@ -1137,6 +1155,13 @@ class AdvancedParameters(WindowType):
1137
1155
  self.message.setStyleSheet("color: rgb(230, 145, 18)")
1138
1156
 
1139
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
+ """
1140
1165
  self.automatically_crop.setChecked(self.parent().po.all['automatically_crop'])
1141
1166
  self.subtract_background.setChecked(self.parent().po.vars['subtract_background'])
1142
1167
  self.keep_cell_and_back_for_all_folders.setChecked(self.parent().po.all['keep_cell_and_back_for_all_folders'])
@@ -1153,8 +1178,6 @@ class AdvancedParameters(WindowType):
1153
1178
  self.oscillation_period.setValue(self.parent().po.vars['expected_oscillation_period'])
1154
1179
  self.minimal_oscillating_cluster_size.setValue(self.parent().po.vars['minimal_oscillating_cluster_size'])
1155
1180
 
1156
- self.network_detection_threshold.setValue(self.parent().po.vars['network_detection_threshold'])
1157
-
1158
1181
  self.do_multiprocessing.setChecked(self.parent().po.all['do_multiprocessing'])
1159
1182
  self.max_core_nb.setValue(self.parent().po.all['cores'])
1160
1183
  self.min_memory_left.setValue(self.parent().po.vars['min_ram_free'])
@@ -1189,11 +1212,20 @@ class AdvancedParameters(WindowType):
1189
1212
  self.parent().change_widget(3) # ImageAnalysisWindow ThirdWidget
1190
1213
 
1191
1214
  def ok_is_clicked(self):
1192
- """ Triggered when ok is clicked, save the directory all_vars.pkl and go back to the previous window"""
1193
- # if self.mesh_side_length.value() <= self.mesh_step_length.value():
1194
- # self.message.setText('The mesh side has to be inferior to the mesh step')
1195
- # self.message.setStyleSheet("color: rgb(230, 145, 18)")
1196
- # 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
+ """
1197
1229
  self.parent().po.all['automatically_crop'] = self.automatically_crop.isChecked()
1198
1230
  self.parent().po.vars['subtract_background'] = self.subtract_background.isChecked()
1199
1231
  self.parent().po.all['keep_cell_and_back_for_all_folders'] = self.keep_cell_and_back_for_all_folders.isChecked()
@@ -1202,16 +1234,32 @@ class AdvancedParameters(WindowType):
1202
1234
  self.parent().po.vars['periphery_width'] = int(self.periphery_width.value())
1203
1235
  self.parent().po.vars['max_periphery_growth'] = int(self.max_periphery_growth.value())
1204
1236
 
1205
- # if self.parent().po.vars['origin_state'] == "invisible":
1206
1237
  self.parent().po.all['first_move_threshold_in_mm²'] = self.first_move_threshold.value()
1207
1238
  self.parent().po.vars['output_in_mm'] = self.pixels_to_mm.isChecked()
1208
1239
  self.parent().po.all['automatic_size_thresholding'] = self.do_automatic_size_thresholding.isChecked()
1209
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
+
1210
1260
  self.parent().po.vars['expected_oscillation_period'] = self.oscillation_period.value()
1211
1261
  self.parent().po.vars['minimal_oscillating_cluster_size'] = int(self.minimal_oscillating_cluster_size.value())
1212
1262
 
1213
- self.parent().po.vars['network_detection_threshold'] = int(np.round(self.network_detection_threshold.value()))
1214
-
1215
1263
  self.parent().po.all['do_multiprocessing'] = self.do_multiprocessing.isChecked()
1216
1264
  self.parent().po.all['cores'] = np.uint8(self.max_core_nb.value())
1217
1265
  self.parent().po.vars['min_ram_free'] = self.min_memory_left.value()
@@ -1242,7 +1290,6 @@ class AdvancedParameters(WindowType):
1242
1290
 
1243
1291
  previous_csc = deepcopy(self.parent().po.vars['convert_for_motion'])
1244
1292
  self.save_user_defined_csc()
1245
- print(self.parent().po.vars['convert_for_motion'])
1246
1293
  if self.parent().po.first_exp_ready_to_run:
1247
1294
  are_dicts_equal: bool = True
1248
1295
  for key in previous_csc.keys():
@@ -1265,15 +1312,7 @@ class AdvancedParameters(WindowType):
1265
1312
  self.parent().change_widget(3) # ImageAnalysisWindow ThirdWidget
1266
1313
 
1267
1314
  def closeEvent(self, event):
1315
+ """
1316
+ Handle the close event for a QWidget.
1317
+ """
1268
1318
  event.accept
1269
-
1270
-
1271
- # if __name__ == "__main__":
1272
- # from cellects.gui.cellects import CellectsMainWidget
1273
- # import sys
1274
- # app = QtWidgets.QApplication([])
1275
- # parent = CellectsMainWidget()
1276
- # session = AdvancedParameters(parent, False)
1277
- # parent.insertWidget(0, session)
1278
- # parent.show()
1279
- # sys.exit(app.exec())