celldetective 1.4.0__py3-none-any.whl → 1.4.1.post1__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 (78) hide show
  1. celldetective/_version.py +1 -1
  2. celldetective/exceptions.py +11 -0
  3. celldetective/filters.py +7 -1
  4. celldetective/gui/InitWindow.py +4 -1
  5. celldetective/gui/__init__.py +2 -9
  6. celldetective/gui/about.py +2 -2
  7. celldetective/gui/base_annotator.py +786 -0
  8. celldetective/gui/classifier_widget.py +18 -13
  9. celldetective/gui/configure_new_exp.py +51 -30
  10. celldetective/gui/control_panel.py +10 -7
  11. celldetective/gui/{signal_annotator.py → event_annotator.py} +473 -1437
  12. celldetective/gui/generic_signal_plot.py +2 -1
  13. celldetective/gui/gui_utils.py +5 -2
  14. celldetective/gui/help/neighborhood.json +2 -2
  15. celldetective/gui/layouts.py +21 -11
  16. celldetective/gui/{signal_annotator2.py → pair_event_annotator.py} +3 -1
  17. celldetective/gui/process_block.py +129 -91
  18. celldetective/gui/processes/downloader.py +37 -34
  19. celldetective/gui/processes/measure_cells.py +14 -8
  20. celldetective/gui/processes/segment_cells.py +438 -314
  21. celldetective/gui/processes/track_cells.py +12 -13
  22. celldetective/gui/settings/__init__.py +7 -0
  23. celldetective/gui/settings/_settings_base.py +70 -0
  24. celldetective/gui/{retrain_signal_model_options.py → settings/_settings_event_model_training.py} +35 -91
  25. celldetective/gui/{measurement_options.py → settings/_settings_measurements.py} +28 -81
  26. celldetective/gui/{neighborhood_options.py → settings/_settings_neighborhood.py} +1 -1
  27. celldetective/gui/settings/_settings_segmentation.py +49 -0
  28. celldetective/gui/{retrain_segmentation_model_options.py → settings/_settings_segmentation_model_training.py} +33 -79
  29. celldetective/gui/{signal_annotator_options.py → settings/_settings_signal_annotator.py} +73 -95
  30. celldetective/gui/{btrack_options.py → settings/_settings_tracking.py} +64 -87
  31. celldetective/gui/styles.py +2 -1
  32. celldetective/gui/survival_ui.py +1 -1
  33. celldetective/gui/tableUI.py +25 -0
  34. celldetective/gui/table_ops/__init__.py +0 -0
  35. celldetective/gui/table_ops/merge_groups.py +118 -0
  36. celldetective/gui/viewers.py +3 -5
  37. celldetective/gui/workers.py +0 -2
  38. celldetective/io.py +98 -55
  39. celldetective/links/zenodo.json +145 -144
  40. celldetective/measure.py +31 -26
  41. celldetective/preprocessing.py +34 -21
  42. celldetective/regionprops/_regionprops.py +16 -5
  43. celldetective/scripts/measure_cells.py +5 -5
  44. celldetective/scripts/measure_relative.py +16 -11
  45. celldetective/scripts/segment_cells.py +4 -4
  46. celldetective/scripts/segment_cells_thresholds.py +3 -3
  47. celldetective/scripts/track_cells.py +7 -7
  48. celldetective/scripts/train_segmentation_model.py +10 -1
  49. celldetective/tracking.py +10 -4
  50. celldetective/utils.py +59 -58
  51. {celldetective-1.4.0.dist-info → celldetective-1.4.1.post1.dist-info}/METADATA +1 -1
  52. celldetective-1.4.1.post1.dist-info/RECORD +123 -0
  53. tests/gui/__init__.py +0 -0
  54. tests/gui/test_new_project.py +228 -0
  55. tests/{test_qt.py → gui/test_project.py} +22 -26
  56. tests/test_preprocessing.py +2 -2
  57. celldetective/models/segmentation_effectors/ricm_bf_all_last/config_input.json +0 -79
  58. celldetective/models/segmentation_effectors/ricm_bf_all_last/ricm_bf_all_last +0 -0
  59. celldetective/models/segmentation_effectors/ricm_bf_all_last/training_instructions.json +0 -37
  60. celldetective/models/segmentation_effectors/test-transfer/config_input.json +0 -39
  61. celldetective/models/segmentation_effectors/test-transfer/test-transfer +0 -0
  62. celldetective/models/signal_detection/NucCond/classification_loss.png +0 -0
  63. celldetective/models/signal_detection/NucCond/classifier.h5 +0 -0
  64. celldetective/models/signal_detection/NucCond/config_input.json +0 -1
  65. celldetective/models/signal_detection/NucCond/log_classifier.csv +0 -126
  66. celldetective/models/signal_detection/NucCond/log_regressor.csv +0 -282
  67. celldetective/models/signal_detection/NucCond/regression_loss.png +0 -0
  68. celldetective/models/signal_detection/NucCond/regressor.h5 +0 -0
  69. celldetective/models/signal_detection/NucCond/scores.npy +0 -0
  70. celldetective/models/signal_detection/NucCond/test_confusion_matrix.png +0 -0
  71. celldetective/models/signal_detection/NucCond/test_regression.png +0 -0
  72. celldetective/models/signal_detection/NucCond/validation_confusion_matrix.png +0 -0
  73. celldetective/models/signal_detection/NucCond/validation_regression.png +0 -0
  74. celldetective-1.4.0.dist-info/RECORD +0 -131
  75. {celldetective-1.4.0.dist-info → celldetective-1.4.1.post1.dist-info}/WHEEL +0 -0
  76. {celldetective-1.4.0.dist-info → celldetective-1.4.1.post1.dist-info}/entry_points.txt +0 -0
  77. {celldetective-1.4.0.dist-info → celldetective-1.4.1.post1.dist-info}/licenses/LICENSE +0 -0
  78. {celldetective-1.4.0.dist-info → celldetective-1.4.1.post1.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,11 @@
1
- from PyQt5.QtWidgets import QApplication,QRadioButton, QScrollArea, QComboBox, QFrame, QFileDialog, QGridLayout, QLineEdit, QVBoxLayout, QLabel, QHBoxLayout, QPushButton
1
+ from PyQt5.QtWidgets import QRadioButton, QComboBox, QFrame, QFileDialog, QGridLayout, QLineEdit, QVBoxLayout, QLabel, QHBoxLayout, QPushButton
2
2
  from PyQt5.QtCore import Qt, QSize
3
- from PyQt5.QtGui import QDoubleValidator, QIntValidator
4
- from celldetective.gui.gui_utils import center_window, generic_message
3
+ from celldetective.gui.gui_utils import generic_message
5
4
  from celldetective.gui.layouts import ChannelNormGenerator
6
5
 
7
6
  from superqt import QLabeledDoubleSlider,QLabeledSlider
8
7
  from superqt.fonticon import icon
9
8
  from fonticon_mdi6 import MDI6
10
- from celldetective.utils import get_software_location
11
9
  from celldetective.io import get_segmentation_datasets_list, locate_segmentation_dataset, get_segmentation_models_list
12
10
  from celldetective.segmentation import train_segmentation_model
13
11
  from celldetective.gui.layouts import CellposeParamsWidget
@@ -16,10 +14,9 @@ import json
16
14
  import os
17
15
  from glob import glob
18
16
  from datetime import datetime
19
- from celldetective.gui import CelldetectiveMainWindow, CelldetectiveWidget
17
+ from celldetective.gui.settings._settings_base import CelldetectiveSettingsPanel
20
18
 
21
-
22
- class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
19
+ class SettingsSegmentationModelTraining(CelldetectiveSettingsPanel):
23
20
 
24
21
  """
25
22
  UI to set segmentation model training instructions.
@@ -28,85 +25,56 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
28
25
 
29
26
  def __init__(self, parent_window=None):
30
27
 
31
- super().__init__()
32
28
  self.parent_window = parent_window
33
29
  self.use_gpu = self.parent_window.use_gpu
34
- self.setWindowTitle("Train segmentation model")
35
30
  self.mode = self.parent_window.mode
36
31
  self.exp_dir = self.parent_window.exp_dir
37
- self.soft_path = get_software_location()
38
- self.pretrained_model = None
32
+ self.pretrained_model = None
39
33
  self.dataset_folder = None
40
- self.software_models_dir = os.sep.join([self.soft_path, 'celldetective', 'models', f'segmentation_{self.mode}'])
41
-
42
- self.onlyFloat = QDoubleValidator()
43
- self.onlyInt = QIntValidator()
44
-
45
- self.screen_height = self.parent_window.parent_window.parent_window.screen_height
46
- center_window(self)
47
-
48
- self.setMinimumWidth(500)
49
- self.setMinimumHeight(int(0.3*self.screen_height))
50
- self.setMaximumHeight(int(0.8*self.screen_height))
51
- self.populate_widget()
52
- #self.load_previous_measurement_instructions()
34
+ super().__init__(title="Train segmentation model")
53
35
 
54
- def populate_widget(self):
36
+ self.software_models_dir = os.sep.join([self._software_path, 'celldetective', 'models', f'segmentation_{self.mode}'])
37
+ self._add_to_layout()
38
+ self._load_previous_instructions()
39
+
40
+ self._adjustSize()
41
+ self.resize(int(self.width()), int(self._screen_height * 0.8))
42
+
43
+ def _add_to_layout(self):
44
+
45
+ self._layout.addWidget(self.model_frame)
46
+ self._layout.addWidget(self.data_frame)
47
+ self._layout.addWidget(self.hyper_frame)
48
+ self._layout.addWidget(self.submit_warning)
49
+ self._layout.addWidget(self.submit_btn)
50
+
51
+ def _create_widgets(self):
55
52
 
56
53
  """
57
54
  Create the multibox design.
58
55
 
59
56
  """
60
57
 
61
- # Create button widget and layout
62
- self.scroll_area = QScrollArea(self)
63
- self.button_widget = CelldetectiveWidget()
64
- self.main_layout = QVBoxLayout()
65
- self.button_widget.setLayout(self.main_layout)
66
- self.main_layout.setContentsMargins(30,30,30,30)
67
-
68
- # first frame for FEATURES
58
+ super()._create_widgets()
69
59
  self.model_frame = QFrame()
70
60
  self.model_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
71
61
  self.populate_model_frame()
72
- self.main_layout.addWidget(self.model_frame)
73
62
 
74
63
  self.data_frame = QFrame()
75
64
  self.data_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
76
65
  self.populate_data_frame()
77
- self.main_layout.addWidget(self.data_frame)
78
66
 
79
67
  self.hyper_frame = QFrame()
80
68
  self.hyper_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
81
69
  self.populate_hyper_frame()
82
- self.main_layout.addWidget(self.hyper_frame)
83
70
 
84
- self.submit_btn = QPushButton('Train')
85
- self.submit_btn.setStyleSheet(self.button_style_sheet)
86
- self.submit_btn.clicked.connect(self.prep_model)
87
- self.main_layout.addWidget(self.submit_btn)
88
71
  self.submit_btn.setEnabled(False)
89
72
  self.submit_warning = QLabel('')
90
- self.main_layout.addWidget(self.submit_warning)
73
+ self.submit_btn.setText("Train")
91
74
 
92
75
  self.spatial_calib_le.textChanged.connect(self.activate_train_btn)
93
76
  self.modelname_le.setText(f"Untitled_model_{datetime.today().strftime('%Y-%m-%d')}")
94
77
 
95
- #self.populate_left_panel()
96
- #grid.addLayout(self.left_side, 0, 0, 1, 1)
97
- self.button_widget.adjustSize()
98
-
99
- self.scroll_area.setAlignment(Qt.AlignCenter)
100
- self.scroll_area.setWidget(self.button_widget)
101
- self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
102
- self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
103
- self.scroll_area.setWidgetResizable(True)
104
- self.setCentralWidget(self.scroll_area)
105
- self.show()
106
-
107
- QApplication.processEvents()
108
- self.adjustScrollArea()
109
-
110
78
  def populate_hyper_frame(self):
111
79
 
112
80
  """
@@ -135,14 +103,14 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
135
103
  lr_layout = QHBoxLayout()
136
104
  lr_layout.addWidget(QLabel('learning rate: '),30)
137
105
  self.lr_le = QLineEdit('0,0003')
138
- self.lr_le.setValidator(self.onlyFloat)
106
+ self.lr_le.setValidator(self._floatValidator)
139
107
  lr_layout.addWidget(self.lr_le, 70)
140
108
  layout.addLayout(lr_layout)
141
109
 
142
110
  bs_layout = QHBoxLayout()
143
111
  bs_layout.addWidget(QLabel('batch size: '),30)
144
112
  self.bs_le = QLineEdit('8')
145
- self.bs_le.setValidator(self.onlyInt)
113
+ self.bs_le.setValidator(self._intValidator)
146
114
  bs_layout.addWidget(self.bs_le, 70)
147
115
  layout.addLayout(bs_layout)
148
116
 
@@ -318,7 +286,7 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
318
286
  parent_pxtoum = f"{self.parent_window.parent_window.PxToUm}"
319
287
  self.spatial_calib_le = QLineEdit(parent_pxtoum.replace('.',','))
320
288
  self.spatial_calib_le.setPlaceholderText('e.g. 0.1 µm per pixel')
321
- self.spatial_calib_le.setValidator(self.onlyFloat)
289
+ self.spatial_calib_le.setValidator(self._floatValidator)
322
290
  spatial_calib_layout.addWidget(self.spatial_calib_le, 70)
323
291
  layout.addLayout(spatial_calib_layout)
324
292
 
@@ -349,17 +317,11 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
349
317
 
350
318
  def showDialog_pretrained(self):
351
319
 
352
- # try:
353
- # self.cancel_pretrained.click()
354
- # except Exception as e:
355
- # print(e)
356
- # pass
357
-
358
320
  self.clear_pretrained()
359
321
  self.pretrained_model = None
360
322
  self.pretrained_model = QFileDialog.getExistingDirectory(
361
323
  self, "Open Directory",
362
- os.sep.join([self.soft_path, 'celldetective', 'models', f'segmentation_generic','']),
324
+ os.sep.join([self._software_path, 'celldetective', 'models', f'segmentation_generic','']),
363
325
  QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks,
364
326
  )
365
327
 
@@ -531,18 +493,7 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
531
493
 
532
494
  self.spatial_calib_le.setText(str(spatial_calib).replace('.',','))
533
495
 
534
- def adjustScrollArea(self):
535
-
536
- """
537
- Auto-adjust scroll area to fill space
538
- (from https://stackoverflow.com/questions/66417576/make-qscrollarea-use-all-available-space-of-qmainwindow-height-axis)
539
- """
540
-
541
- step = 5
542
- while self.scroll_area.verticalScrollBar().isVisible() and self.height() < self.maximumHeight():
543
- self.resize(self.width(), self.height() + step)
544
-
545
- def prep_model(self):
496
+ def _write_instructions(self):
546
497
 
547
498
  model_name = self.modelname_le.text()
548
499
  pretrained_model = self.pretrained_model
@@ -623,4 +574,7 @@ class ConfigSegmentationModelTraining(CelldetectiveMainWindow):
623
574
 
624
575
  self.parent_window.init_seg_model_list()
625
576
  idx = self.parent_window.seg_model_list.findText(model_name)
626
- self.parent_window.seg_model_list.setCurrentIndex(idx)
577
+ self.parent_window.seg_model_list.setCurrentIndex(idx)
578
+
579
+ def _load_previous_instructions(self):
580
+ pass
@@ -1,5 +1,5 @@
1
1
  """
2
- Copright © 2023 Laboratoire Adhesion et Inflammation, Authored by Remy Torro.
2
+ Copyright © 2023 Laboratoire Adhesion et Inflammation, Authored by Remy Torro.
3
3
  """
4
4
 
5
5
  from PyQt5.QtWidgets import QComboBox, QLabel, QRadioButton, QLineEdit, QApplication, QPushButton, QScrollArea, QVBoxLayout, QHBoxLayout
@@ -12,9 +12,9 @@ import numpy as np
12
12
  from superqt.fonticon import icon
13
13
  from fonticon_mdi6 import MDI6
14
14
  import os
15
- from celldetective.gui import CelldetectiveWidget, CelldetectiveMainWindow
15
+ from celldetective.gui.settings._settings_base import CelldetectiveSettingsPanel
16
16
 
17
- class ConfigSignalAnnotator(CelldetectiveMainWindow):
17
+ class SettingsSignalAnnotator(CelldetectiveSettingsPanel):
18
18
 
19
19
  """
20
20
  UI to set normalization and animation parameters for the annotator tool.
@@ -23,65 +23,94 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
23
23
 
24
24
  def __init__(self, parent_window=None):
25
25
 
26
- super().__init__()
27
26
  self.parent_window = parent_window
28
- self.setWindowTitle("Configure signal annotator")
29
27
  self.mode = self.parent_window.mode
30
28
  self.exp_dir = self.parent_window.exp_dir
31
- self.soft_path = get_software_location()
32
29
 
33
30
  self.instructions_path = self.parent_window.exp_dir + f"configs/signal_annotator_config_{self.mode}.json"
34
31
  if self.mode == "pairs":
35
32
  self.instructions_path = self.parent_window.exp_dir + "configs/signal_annotator_config_neighborhood.json"
36
33
 
37
- exp_config = self.exp_dir +"config.ini"
38
- #self.config_path = self.exp_dir + self.config_name
39
34
  self.channel_names, self.channels = extract_experiment_channels(self.exp_dir)
40
35
  self.channel_names = np.array(self.channel_names)
41
36
  self.channels = np.array(self.channels)
42
37
  self.log_option = False
38
+
39
+ super().__init__(title="Configure signal annotator")
43
40
 
44
- self.screen_height = self.parent_window.parent_window.parent_window.screen_height
45
- center_window(self)
41
+ self._add_to_layout()
42
+ self._load_previous_instructions()
43
+
44
+ self._adjustSize()
45
+ self.resize(int(self.width()), int(self._screen_height * 0.55))
46
+
47
+ def _add_to_layout(self):
48
+
49
+ sub_layout = QVBoxLayout()
50
+ sub_layout.setContentsMargins(10,10,10,20)
51
+ sub_layout.setContentsMargins(30,30,30,30)
52
+ sub_layout.addWidget(self._modality_lbl)
53
+
54
+ # Create radio buttons
55
+ option_layout = QHBoxLayout()
56
+ option_layout.addWidget(self.gs_btn, alignment=Qt.AlignCenter)
57
+ option_layout.addWidget(self.rgb_btn, alignment=Qt.AlignCenter)
58
+ sub_layout.addLayout(option_layout)
59
+
60
+ btn_hbox = QHBoxLayout()
61
+ btn_hbox.addWidget(QLabel(''), 90)
62
+ btn_hbox.addWidget(self.log_btn, 5,alignment=Qt.AlignRight)
63
+ btn_hbox.addWidget(self.percentile_btn, 5,alignment=Qt.AlignRight)
64
+ sub_layout.addLayout(btn_hbox)
46
65
 
47
- self.setMinimumHeight(int(0.4*self.screen_height))
48
- self.setMaximumHeight(int(0.8*self.screen_height))
49
- self.populate_widget()
50
- #self.load_previous_measurement_instructions()
66
+ for i in range(3):
67
+ hlayout = QHBoxLayout()
68
+ hlayout.addWidget(self.channel_cbs_lbls[i], 20)
69
+ hlayout.addWidget(self.channel_cbs[i], 80)
70
+ sub_layout.addLayout(hlayout)
51
71
 
72
+ hlayout2 = QHBoxLayout()
73
+ hlayout2.addWidget(self.min_val_lbls[i], 20)
74
+ hlayout2.addWidget(self.min_val_les[i], 80)
75
+ sub_layout.addLayout(hlayout2)
76
+
77
+ hlayout3 = QHBoxLayout()
78
+ hlayout3.addWidget(self.max_val_lbls[i], 20)
79
+ hlayout3.addWidget(self.max_val_les[i], 80)
80
+ sub_layout.addLayout(hlayout3)
52
81
 
53
- def populate_widget(self):
82
+ sub_layout.addWidget(self.hsep)
83
+ hbox_frac = QHBoxLayout()
84
+ hbox_frac.addWidget(self._fraction_lbl, 20)
85
+ hbox_frac.addWidget(self.fraction_slider, 80)
86
+ sub_layout.addLayout(hbox_frac)
87
+
88
+ hbox_interval = QHBoxLayout()
89
+ hbox_interval.addWidget(self._interval_lbl, 20)
90
+ hbox_interval.addWidget(self.interval_slider, 80)
91
+ sub_layout.addLayout(hbox_interval)
92
+
93
+ self._layout.addLayout(sub_layout)
94
+
95
+ self._layout.addWidget(self.submit_btn)
96
+
97
+ def _create_widgets(self):
54
98
 
55
99
  """
56
100
  Create the widgets.
57
101
 
58
102
  """
59
-
60
- self.scroll_area = QScrollArea(self)
61
- self.button_widget = CelldetectiveWidget()
62
-
63
- self.main_layout = QVBoxLayout()
64
- self.main_layout.setContentsMargins(30,30,30,30)
65
-
66
- sub_layout = QVBoxLayout()
67
- sub_layout.setContentsMargins(10,10,10,20)
68
-
69
- self.button_widget.setLayout(self.main_layout)
70
- sub_layout.setContentsMargins(30,30,30,30)
71
-
72
- sub_layout.addWidget(QLabel('Modality: '))
103
+ super()._create_widgets()
104
+
105
+ self._modality_lbl = QLabel("Modality: ")
106
+ self._fraction_lbl = QLabel("fraction: ")
107
+ self._interval_lbl = QLabel('interval [ms]: ')
73
108
 
74
- # Create radio buttons
75
- option_layout = QHBoxLayout()
76
109
  self.gs_btn = QRadioButton('grayscale')
77
110
  self.gs_btn.setChecked(True)
78
- option_layout.addWidget(self.gs_btn, alignment=Qt.AlignCenter)
79
-
111
+
80
112
  self.rgb_btn = QRadioButton('RGB')
81
- option_layout.addWidget(self.rgb_btn, alignment=Qt.AlignCenter)
82
- sub_layout.addLayout(option_layout)
83
113
 
84
- btn_hbox = QHBoxLayout()
85
114
 
86
115
  self.percentile_btn = QPushButton()
87
116
  self.percentile_btn.setIcon(icon(MDI6.percent_circle_outline,color="black"))
@@ -97,11 +126,6 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
97
126
  self.log_btn.setToolTip("Log-transform the intensities.")
98
127
  self.log_btn.setIconSize(QSize(20, 20))
99
128
 
100
- btn_hbox.addWidget(QLabel(''), 90)
101
- btn_hbox.addWidget(self.log_btn, 5,alignment=Qt.AlignRight)
102
- btn_hbox.addWidget(self.percentile_btn, 5,alignment=Qt.AlignRight)
103
- sub_layout.addLayout(btn_hbox)
104
-
105
129
  self.channel_cbs = [QComboBox() for i in range(3)]
106
130
  self.channel_cbs_lbls = [QLabel() for i in range(3)]
107
131
 
@@ -115,23 +139,13 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
115
139
 
116
140
  for i in range(3):
117
141
 
118
- hlayout = QHBoxLayout()
119
142
  self.channel_cbs[i].addItems(self.channel_names)
120
143
  self.channel_cbs[i].setCurrentIndex(i)
121
144
  self.channel_cbs_lbls[i].setText(self.rgb_text[i])
122
- hlayout.addWidget(self.channel_cbs_lbls[i], 20)
123
- hlayout.addWidget(self.channel_cbs[i], 80)
124
- sub_layout.addLayout(hlayout)
145
+
146
+ self.min_val_les[i].setValidator(self._floatValidator)
147
+ self.max_val_les[i].setValidator(self._floatValidator)
125
148
 
126
- hlayout2 = QHBoxLayout()
127
- hlayout2.addWidget(self.min_val_lbls[i], 20)
128
- hlayout2.addWidget(self.min_val_les[i], 80)
129
- sub_layout.addLayout(hlayout2)
130
-
131
- hlayout3 = QHBoxLayout()
132
- hlayout3.addWidget(self.max_val_lbls[i], 20)
133
- hlayout3.addWidget(self.max_val_les[i], 80)
134
- sub_layout.addLayout(hlayout3)
135
149
 
136
150
  self.enable_channels()
137
151
 
@@ -139,10 +153,6 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
139
153
  self.rgb_btn.toggled.connect(self.enable_channels)
140
154
 
141
155
  self.hsep = QHSeperationLine()
142
- sub_layout.addWidget(self.hsep)
143
-
144
- hbox_frac = QHBoxLayout()
145
- hbox_frac.addWidget(QLabel('fraction: '), 20)
146
156
 
147
157
  self.fraction_slider = QLabeledDoubleSlider()
148
158
  self.fraction_slider.setSingleStep(0.05)
@@ -152,13 +162,6 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
152
162
  self.fraction_slider.setRange(0.1,1)
153
163
  self.fraction_slider.setValue(0.25)
154
164
 
155
- hbox_frac.addWidget(self.fraction_slider, 80)
156
- sub_layout.addLayout(hbox_frac)
157
-
158
-
159
- hbox_interval = QHBoxLayout()
160
- hbox_interval.addWidget(QLabel('interval [ms]: '), 20)
161
-
162
165
  self.interval_slider = QLabeledSlider()
163
166
  self.interval_slider.setSingleStep(1)
164
167
  self.interval_slider.setTickInterval(1)
@@ -166,29 +169,6 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
166
169
  self.interval_slider.setOrientation(Qt.Horizontal)
167
170
  self.interval_slider.setRange(1,1000)
168
171
  self.interval_slider.setValue(1)
169
- hbox_interval.addWidget(self.interval_slider, 80)
170
- sub_layout.addLayout(hbox_interval)
171
-
172
- self.main_layout.addLayout(sub_layout)
173
-
174
- self.submit_btn = QPushButton('Save')
175
- self.submit_btn.setStyleSheet(self.button_style_sheet)
176
- self.submit_btn.clicked.connect(self.write_instructions)
177
- self.main_layout.addWidget(self.submit_btn)
178
-
179
-
180
- self.button_widget.adjustSize()
181
- self.scroll_area.setAlignment(Qt.AlignCenter)
182
- self.scroll_area.setWidget(self.button_widget)
183
- self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
184
- self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
185
- self.scroll_area.setWidgetResizable(True)
186
- self.setCentralWidget(self.scroll_area)
187
- self.show()
188
-
189
- self.read_instructions()
190
-
191
- QApplication.processEvents()
192
172
 
193
173
  def enable_channels(self):
194
174
 
@@ -207,7 +187,6 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
207
187
  self.channel_cbs_lbls[k].setEnabled(False)
208
188
 
209
189
  for k in range(3):
210
-
211
190
  self.min_val_les[k].setEnabled(False)
212
191
  self.min_val_lbls[k].setEnabled(False)
213
192
  self.max_val_les[k].setEnabled(False)
@@ -219,7 +198,6 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
219
198
  self.percentile_btn.setEnabled(True)
220
199
 
221
200
  for k in range(3):
222
-
223
201
  self.channel_cbs[k].setEnabled(True)
224
202
  self.channel_cbs_lbls[k].setEnabled(True)
225
203
 
@@ -256,7 +234,7 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
256
234
  self.max_val_lbls[k].setText('Max percentile: ')
257
235
  self.max_val_les[k].setText('99.99')
258
236
 
259
- def write_instructions(self):
237
+ def _write_instructions(self):
260
238
 
261
239
  """
262
240
  Save the current configuration.
@@ -267,7 +245,7 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
267
245
  max_i = 3 if self.rgb_btn.isChecked() else 1
268
246
  channels = []
269
247
  for i in range(max_i):
270
- channels.append([self.channel_cbs[i].currentText(), float(self.min_val_les[i].text()), float(self.max_val_les[i].text())])
248
+ channels.append([self.channel_cbs[i].currentText(), float(self.min_val_les[i].text().replace(',','.')), float(self.max_val_les[i].text().replace(',','.'))])
271
249
  instructions.update({'channels': channels})
272
250
 
273
251
  print('Instructions: ', instructions)
@@ -277,7 +255,7 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
277
255
  print('Done.')
278
256
  self.close()
279
257
 
280
- def read_instructions(self):
258
+ def _load_previous_instructions(self):
281
259
 
282
260
  """
283
261
  Read and set the widgets to the last configuration.
@@ -312,8 +290,8 @@ class ConfigSignalAnnotator(CelldetectiveMainWindow):
312
290
  for i in range(max_iter):
313
291
  idx = self.channel_cbs[i].findText(channels[i][0])
314
292
  self.channel_cbs[i].setCurrentIndex(idx)
315
- self.min_val_les[i].setText(str(channels[i][1]))
316
- self.max_val_les[i].setText(str(channels[i][2]))
293
+ self.min_val_les[i].setText(str(channels[i][1]).replace('.',','))
294
+ self.max_val_les[i].setText(str(channels[i][2]).replace('.',','))
317
295
 
318
296
  if 'fraction' in instructions:
319
297
  fraction = instructions['fraction']