celldetective 1.0.2__py3-none-any.whl → 1.1.0__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.
- celldetective/__main__.py +2 -2
- celldetective/events.py +2 -44
- celldetective/filters.py +4 -5
- celldetective/gui/__init__.py +1 -1
- celldetective/gui/analyze_block.py +37 -10
- celldetective/gui/btrack_options.py +24 -23
- celldetective/gui/classifier_widget.py +62 -19
- celldetective/gui/configure_new_exp.py +32 -35
- celldetective/gui/control_panel.py +115 -81
- celldetective/gui/gui_utils.py +674 -396
- celldetective/gui/json_readers.py +7 -6
- celldetective/gui/layouts.py +755 -0
- celldetective/gui/measurement_options.py +168 -487
- celldetective/gui/neighborhood_options.py +322 -270
- celldetective/gui/plot_measurements.py +1114 -0
- celldetective/gui/plot_signals_ui.py +20 -20
- celldetective/gui/process_block.py +449 -169
- celldetective/gui/retrain_segmentation_model_options.py +27 -26
- celldetective/gui/retrain_signal_model_options.py +25 -24
- celldetective/gui/seg_model_loader.py +31 -27
- celldetective/gui/signal_annotator.py +2326 -2295
- celldetective/gui/signal_annotator_options.py +18 -16
- celldetective/gui/styles.py +16 -1
- celldetective/gui/survival_ui.py +61 -39
- celldetective/gui/tableUI.py +60 -23
- celldetective/gui/thresholds_gui.py +68 -66
- celldetective/gui/viewers.py +596 -0
- celldetective/io.py +234 -23
- celldetective/measure.py +37 -32
- celldetective/neighborhood.py +495 -27
- celldetective/preprocessing.py +683 -0
- celldetective/scripts/analyze_signals.py +7 -0
- celldetective/scripts/measure_cells.py +12 -0
- celldetective/scripts/segment_cells.py +5 -0
- celldetective/scripts/track_cells.py +11 -0
- celldetective/signals.py +221 -98
- celldetective/tracking.py +0 -1
- celldetective/utils.py +178 -36
- celldetective-1.1.0.dist-info/METADATA +305 -0
- celldetective-1.1.0.dist-info/RECORD +80 -0
- {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/top_level.txt +1 -0
- tests/__init__.py +0 -0
- tests/test_events.py +28 -0
- tests/test_filters.py +24 -0
- tests/test_io.py +70 -0
- tests/test_measure.py +141 -0
- tests/test_neighborhood.py +70 -0
- tests/test_segmentation.py +93 -0
- tests/test_signals.py +135 -0
- tests/test_tracking.py +164 -0
- tests/test_utils.py +71 -0
- celldetective-1.0.2.dist-info/METADATA +0 -192
- celldetective-1.0.2.dist-info/RECORD +0 -66
- {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/LICENSE +0 -0
- {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/WHEEL +0 -0
- {celldetective-1.0.2.dist-info → celldetective-1.1.0.dist-info}/entry_points.txt +0 -0
|
@@ -37,28 +37,33 @@ from pathlib import Path, PurePath
|
|
|
37
37
|
import gc
|
|
38
38
|
from stardist import fill_label_holes
|
|
39
39
|
|
|
40
|
+
from celldetective.gui.viewers import CellEdgeVisualizer
|
|
41
|
+
from celldetective.gui.layouts import ProtocolDesignerLayout, BackgroundFitCorrectionLayout, LocalCorrectionLayout, OperationLayout
|
|
42
|
+
from celldetective.gui.gui_utils import ThresholdLineEdit
|
|
43
|
+
from celldetective.gui import Styles
|
|
40
44
|
|
|
41
|
-
class ConfigMeasurements(QMainWindow):
|
|
45
|
+
class ConfigMeasurements(QMainWindow, Styles):
|
|
42
46
|
"""
|
|
43
47
|
UI to set measurement instructions.
|
|
44
48
|
|
|
45
49
|
"""
|
|
46
50
|
|
|
47
|
-
def __init__(self,
|
|
51
|
+
def __init__(self, parent_window=None):
|
|
48
52
|
|
|
49
53
|
super().__init__()
|
|
50
|
-
|
|
54
|
+
|
|
55
|
+
self.parent_window = parent_window
|
|
51
56
|
self.setWindowTitle("Configure measurements")
|
|
52
57
|
self.setWindowIcon(QIcon(os.sep.join(['celldetective', 'icons', 'mexican-hat.png'])))
|
|
53
|
-
self.mode = self.
|
|
54
|
-
self.exp_dir = self.
|
|
58
|
+
self.mode = self.parent_window.mode
|
|
59
|
+
self.exp_dir = self.parent_window.exp_dir
|
|
55
60
|
self.background_correction = []
|
|
56
61
|
if self.mode == "targets":
|
|
57
62
|
self.config_name = "btrack_config_targets.json"
|
|
58
|
-
self.measure_instructions_path = self.
|
|
63
|
+
self.measure_instructions_path = self.parent_window.exp_dir + "configs/measurement_instructions_targets.json"
|
|
59
64
|
elif self.mode == "effectors":
|
|
60
65
|
self.config_name = "btrack_config_effectors.json"
|
|
61
|
-
self.measure_instructions_path = self.
|
|
66
|
+
self.measure_instructions_path = self.parent_window.exp_dir + "configs/measurement_instructions_effectors.json"
|
|
62
67
|
self.soft_path = get_software_location()
|
|
63
68
|
self.clear_previous = False
|
|
64
69
|
|
|
@@ -68,7 +73,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
68
73
|
self.channel_names = np.array(self.channel_names)
|
|
69
74
|
self.channels = np.array(self.channels)
|
|
70
75
|
|
|
71
|
-
self.screen_height = self.
|
|
76
|
+
self.screen_height = self.parent_window.parent_window.parent_window.screen_height
|
|
72
77
|
center_window(self)
|
|
73
78
|
|
|
74
79
|
self.onlyFloat = QDoubleValidator()
|
|
@@ -96,7 +101,20 @@ class ConfigMeasurements(QMainWindow):
|
|
|
96
101
|
|
|
97
102
|
self.normalisation_frame = QFrame()
|
|
98
103
|
self.normalisation_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
|
|
99
|
-
|
|
104
|
+
|
|
105
|
+
self.local_correction_layout = LocalCorrectionLayout(self)
|
|
106
|
+
self.fit_correction_layout = BackgroundFitCorrectionLayout(self)
|
|
107
|
+
|
|
108
|
+
self.protocol_layout = ProtocolDesignerLayout(parent_window=self,
|
|
109
|
+
tab_layouts=[ self.local_correction_layout, self.fit_correction_layout],
|
|
110
|
+
tab_names=['Local', 'Fit'],
|
|
111
|
+
title='BACKGROUND CORRECTION',
|
|
112
|
+
list_title='Corrections to apply:'
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
self.normalisation_frame.setLayout(self.protocol_layout)
|
|
116
|
+
|
|
117
|
+
#self.populate_normalisation_tabs()
|
|
100
118
|
main_layout.addWidget(self.normalisation_frame)
|
|
101
119
|
|
|
102
120
|
# first frame for FEATURES
|
|
@@ -120,7 +138,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
120
138
|
main_layout.addWidget(self.clear_previous_btn)
|
|
121
139
|
|
|
122
140
|
self.submit_btn = QPushButton('Save')
|
|
123
|
-
self.submit_btn.setStyleSheet(self.
|
|
141
|
+
self.submit_btn.setStyleSheet(self.button_style_sheet)
|
|
124
142
|
self.submit_btn.clicked.connect(self.write_instructions)
|
|
125
143
|
main_layout.addWidget(self.submit_btn)
|
|
126
144
|
|
|
@@ -186,14 +204,14 @@ class ConfigMeasurements(QMainWindow):
|
|
|
186
204
|
radii_layout.addWidget(self.radii_lbl, 90)
|
|
187
205
|
|
|
188
206
|
self.del_radius_btn = QPushButton("")
|
|
189
|
-
self.del_radius_btn.setStyleSheet(self.
|
|
207
|
+
self.del_radius_btn.setStyleSheet(self.button_select_all)
|
|
190
208
|
self.del_radius_btn.setIcon(icon(MDI6.trash_can, color="black"))
|
|
191
209
|
self.del_radius_btn.setToolTip("Remove radius")
|
|
192
210
|
self.del_radius_btn.setIconSize(QSize(20, 20))
|
|
193
211
|
radii_layout.addWidget(self.del_radius_btn, 5)
|
|
194
212
|
|
|
195
213
|
self.add_radius_btn = QPushButton("")
|
|
196
|
-
self.add_radius_btn.setStyleSheet(self.
|
|
214
|
+
self.add_radius_btn.setStyleSheet(self.button_select_all)
|
|
197
215
|
self.add_radius_btn.setIcon(icon(MDI6.plus, color="black"))
|
|
198
216
|
self.add_radius_btn.setToolTip("Add radius")
|
|
199
217
|
self.add_radius_btn.setIconSize(QSize(20, 20))
|
|
@@ -213,14 +231,14 @@ class ConfigMeasurements(QMainWindow):
|
|
|
213
231
|
operation_layout.addWidget(self.op_lbl, 90)
|
|
214
232
|
|
|
215
233
|
self.del_op_btn = QPushButton("")
|
|
216
|
-
self.del_op_btn.setStyleSheet(self.
|
|
234
|
+
self.del_op_btn.setStyleSheet(self.button_select_all)
|
|
217
235
|
self.del_op_btn.setIcon(icon(MDI6.trash_can, color="black"))
|
|
218
236
|
self.del_op_btn.setToolTip("Remove operation")
|
|
219
237
|
self.del_op_btn.setIconSize(QSize(20, 20))
|
|
220
238
|
operation_layout.addWidget(self.del_op_btn, 5)
|
|
221
239
|
|
|
222
240
|
self.add_op_btn = QPushButton("")
|
|
223
|
-
self.add_op_btn.setStyleSheet(self.
|
|
241
|
+
self.add_op_btn.setStyleSheet(self.button_select_all)
|
|
224
242
|
self.add_op_btn.setIcon(icon(MDI6.plus, color="black"))
|
|
225
243
|
self.add_op_btn.setToolTip("Add operation")
|
|
226
244
|
self.add_op_btn.setIconSize(QSize(20, 20))
|
|
@@ -244,13 +262,13 @@ class ConfigMeasurements(QMainWindow):
|
|
|
244
262
|
|
|
245
263
|
self.feature_lbl = QLabel("Add features:")
|
|
246
264
|
self.del_feature_btn = QPushButton("")
|
|
247
|
-
self.del_feature_btn.setStyleSheet(self.
|
|
265
|
+
self.del_feature_btn.setStyleSheet(self.button_select_all)
|
|
248
266
|
self.del_feature_btn.setIcon(icon(MDI6.trash_can, color="black"))
|
|
249
267
|
self.del_feature_btn.setToolTip("Remove feature")
|
|
250
268
|
self.del_feature_btn.setIconSize(QSize(20, 20))
|
|
251
269
|
|
|
252
270
|
self.add_feature_btn = QPushButton("")
|
|
253
|
-
self.add_feature_btn.setStyleSheet(self.
|
|
271
|
+
self.add_feature_btn.setStyleSheet(self.button_select_all)
|
|
254
272
|
self.add_feature_btn.setIcon(icon(MDI6.filter_plus, color="black"))
|
|
255
273
|
self.add_feature_btn.setToolTip("Add feature")
|
|
256
274
|
self.add_feature_btn.setIconSize(QSize(20, 20))
|
|
@@ -276,22 +294,22 @@ class ConfigMeasurements(QMainWindow):
|
|
|
276
294
|
contour_layout.addWidget(self.border_dist_lbl, 90)
|
|
277
295
|
|
|
278
296
|
self.del_contour_btn = QPushButton("")
|
|
279
|
-
self.del_contour_btn.setStyleSheet(self.
|
|
297
|
+
self.del_contour_btn.setStyleSheet(self.button_select_all)
|
|
280
298
|
self.del_contour_btn.setIcon(icon(MDI6.trash_can, color="black"))
|
|
281
299
|
self.del_contour_btn.setToolTip("Remove distance")
|
|
282
300
|
self.del_contour_btn.setIconSize(QSize(20, 20))
|
|
283
301
|
contour_layout.addWidget(self.del_contour_btn, 5)
|
|
284
302
|
|
|
285
303
|
self.add_contour_btn = QPushButton("")
|
|
286
|
-
self.add_contour_btn.setStyleSheet(self.
|
|
304
|
+
self.add_contour_btn.setStyleSheet(self.button_select_all)
|
|
287
305
|
self.add_contour_btn.setIcon(icon(MDI6.plus, color="black"))
|
|
288
306
|
self.add_contour_btn.setToolTip("Add distance")
|
|
289
307
|
self.add_contour_btn.setIconSize(QSize(20, 20))
|
|
290
308
|
contour_layout.addWidget(self.add_contour_btn, 5)
|
|
291
309
|
|
|
292
310
|
self.view_contour_btn = QPushButton("")
|
|
293
|
-
self.view_contour_btn.setStyleSheet(self.
|
|
294
|
-
self.view_contour_btn.setIcon(icon(MDI6.
|
|
311
|
+
self.view_contour_btn.setStyleSheet(self.button_select_all)
|
|
312
|
+
self.view_contour_btn.setIcon(icon(MDI6.eye_plus_outline, color="black"))
|
|
295
313
|
self.view_contour_btn.setToolTip("View contour")
|
|
296
314
|
self.view_contour_btn.setIconSize(QSize(20, 20))
|
|
297
315
|
contour_layout.addWidget(self.view_contour_btn, 5)
|
|
@@ -354,7 +372,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
354
372
|
self.haralick_percentile_min_le = QLineEdit('0.01')
|
|
355
373
|
self.haralick_percentile_max_le = QLineEdit('99.9')
|
|
356
374
|
self.haralick_normalization_mode_btn = QPushButton()
|
|
357
|
-
self.haralick_normalization_mode_btn.setStyleSheet(self.
|
|
375
|
+
self.haralick_normalization_mode_btn.setStyleSheet(self.button_select_all)
|
|
358
376
|
self.haralick_normalization_mode_btn.setIcon(icon(MDI6.percent_circle, color="black"))
|
|
359
377
|
self.haralick_normalization_mode_btn.setIconSize(QSize(20, 20))
|
|
360
378
|
self.haralick_normalization_mode_btn.setToolTip("Switch to absolute normalization values.")
|
|
@@ -371,12 +389,12 @@ class ConfigMeasurements(QMainWindow):
|
|
|
371
389
|
self.haralick_hist_btn = QPushButton()
|
|
372
390
|
self.haralick_hist_btn.clicked.connect(self.control_haralick_intensity_histogram)
|
|
373
391
|
self.haralick_hist_btn.setIcon(icon(MDI6.poll, color="k"))
|
|
374
|
-
self.haralick_hist_btn.setStyleSheet(self.
|
|
392
|
+
self.haralick_hist_btn.setStyleSheet(self.button_select_all)
|
|
375
393
|
|
|
376
394
|
self.haralick_digit_btn = QPushButton()
|
|
377
395
|
self.haralick_digit_btn.clicked.connect(self.control_haralick_digitalization)
|
|
378
396
|
self.haralick_digit_btn.setIcon(icon(MDI6.image_check, color="k"))
|
|
379
|
-
self.haralick_digit_btn.setStyleSheet(self.
|
|
397
|
+
self.haralick_digit_btn.setStyleSheet(self.button_select_all)
|
|
380
398
|
|
|
381
399
|
self.haralick_layout = QVBoxLayout()
|
|
382
400
|
self.haralick_layout.setContentsMargins(20, 20, 20, 20)
|
|
@@ -492,7 +510,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
492
510
|
|
|
493
511
|
print('Writing instructions...')
|
|
494
512
|
measurement_options = {}
|
|
495
|
-
background_correction = self.
|
|
513
|
+
background_correction = self.protocol_layout.protocols
|
|
496
514
|
if not background_correction:
|
|
497
515
|
background_correction = None
|
|
498
516
|
measurement_options.update({'background_correction': background_correction})
|
|
@@ -581,18 +599,20 @@ class ConfigMeasurements(QMainWindow):
|
|
|
581
599
|
measurement_instructions = json.load(f)
|
|
582
600
|
print(measurement_instructions)
|
|
583
601
|
if 'background_correction' in measurement_instructions:
|
|
584
|
-
self.
|
|
585
|
-
if
|
|
586
|
-
self.
|
|
587
|
-
|
|
602
|
+
self.protocol_layout.protocols = measurement_instructions['background_correction']
|
|
603
|
+
if self.protocol_layout.protocols is None:
|
|
604
|
+
self.protocol_layout.protocols = []
|
|
605
|
+
if (self.protocol_layout.protocols is not None) and len(self.protocol_layout.protocols) > 0:
|
|
606
|
+
self.protocol_layout.protocol_list.clear()
|
|
607
|
+
for norm_params in self.protocol_layout.protocols:
|
|
588
608
|
normalisation_description = ""
|
|
589
609
|
for index, (key, value) in enumerate(norm_params.items()):
|
|
590
610
|
if index > 0:
|
|
591
611
|
normalisation_description += ", "
|
|
592
612
|
normalisation_description += str(key) + " : " + str(value)
|
|
593
|
-
self.
|
|
613
|
+
self.protocol_layout.protocol_list.addItem(normalisation_description)
|
|
594
614
|
else:
|
|
595
|
-
self.
|
|
615
|
+
self.protocol_layout.protocol_list.clear()
|
|
596
616
|
if 'features' in measurement_instructions:
|
|
597
617
|
features = measurement_instructions['features']
|
|
598
618
|
if (features is not None) and len(features) > 0:
|
|
@@ -702,30 +722,21 @@ class ConfigMeasurements(QMainWindow):
|
|
|
702
722
|
Load the first frame of the first movie found in the experiment folder as a sample.
|
|
703
723
|
"""
|
|
704
724
|
|
|
705
|
-
movies = glob(self.
|
|
706
|
-
|
|
725
|
+
movies = glob(self.parent_window.parent_window.pos + os.sep.join(['movie', f"{self.parent_window.movie_prefix}*.tif"]))
|
|
726
|
+
|
|
707
727
|
if len(movies) == 0:
|
|
708
728
|
msgBox = QMessageBox()
|
|
709
729
|
msgBox.setIcon(QMessageBox.Warning)
|
|
710
|
-
msgBox.setText("
|
|
730
|
+
msgBox.setText("Please select a position containing a movie...")
|
|
711
731
|
msgBox.setWindowTitle("Warning")
|
|
712
732
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
713
733
|
returnValue = msgBox.exec()
|
|
714
734
|
if returnValue == QMessageBox.Ok:
|
|
715
|
-
self.
|
|
735
|
+
self.current_stack = None
|
|
716
736
|
return None
|
|
717
737
|
else:
|
|
718
|
-
self.
|
|
719
|
-
|
|
720
|
-
len_movie_auto = auto_load_number_of_frames(self.stack0)
|
|
721
|
-
if len_movie_auto is None:
|
|
722
|
-
stack = imread(self.stack0)
|
|
723
|
-
len_movie_auto = len(stack)
|
|
724
|
-
del stack
|
|
725
|
-
gc.collect()
|
|
726
|
-
self.mid_time = len_movie_auto // 2
|
|
727
|
-
self.test_frame = load_frames(n_channels * self.mid_time + np.arange(n_channels), self.stack0, scale=None,
|
|
728
|
-
normalize_input=False)
|
|
738
|
+
self.current_stack = movies[0]
|
|
739
|
+
|
|
729
740
|
|
|
730
741
|
def control_haralick_digitalization(self):
|
|
731
742
|
|
|
@@ -791,119 +802,21 @@ class ConfigMeasurements(QMainWindow):
|
|
|
791
802
|
Show the ROI for the selected contour measurement on experimental data.
|
|
792
803
|
|
|
793
804
|
"""
|
|
794
|
-
|
|
795
|
-
if self.parent.parent.position_list.currentText() == '*':
|
|
796
|
-
msgBox = QMessageBox()
|
|
797
|
-
msgBox.setIcon(QMessageBox.Warning)
|
|
798
|
-
msgBox.setText("Please select a single position to visualize the border selection.")
|
|
799
|
-
msgBox.setWindowTitle("Warning")
|
|
800
|
-
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
801
|
-
returnValue = msgBox.exec()
|
|
802
|
-
if returnValue == QMessageBox.Ok:
|
|
803
|
-
return None
|
|
804
|
-
else:
|
|
805
|
-
return None
|
|
806
|
-
|
|
807
805
|
self.locate_image()
|
|
808
806
|
|
|
809
|
-
self.
|
|
810
|
-
if self.test_mask is None:
|
|
811
|
-
msgBox = QMessageBox()
|
|
812
|
-
msgBox.setIcon(QMessageBox.Warning)
|
|
813
|
-
msgBox.setText("The segmentation results could not be found for this position.")
|
|
814
|
-
msgBox.setWindowTitle("Warning")
|
|
815
|
-
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
816
|
-
returnValue = msgBox.exec()
|
|
817
|
-
if returnValue == QMessageBox.Yes:
|
|
818
|
-
return None
|
|
819
|
-
else:
|
|
820
|
-
return None
|
|
821
|
-
# plt.imshow(self.test_frame[:,:,0])
|
|
822
|
-
# plt.pause(2)
|
|
823
|
-
# plt.close()
|
|
824
|
-
|
|
825
|
-
# plt.imshow(self.test_mask)
|
|
826
|
-
# plt.pause(2)
|
|
827
|
-
# plt.close()
|
|
828
|
-
|
|
829
|
-
if (self.test_frame is not None) and (self.test_mask is not None):
|
|
830
|
-
|
|
831
|
-
values = self.contours_list.list_widget.selectedItems()
|
|
832
|
-
if len(values) > 0:
|
|
833
|
-
distance = values[0].text()
|
|
834
|
-
if '-' in distance:
|
|
835
|
-
if distance[0] != '-':
|
|
836
|
-
border_dist = distance.split('-')
|
|
837
|
-
border_dist = [float(d) for d in border_dist]
|
|
838
|
-
else:
|
|
839
|
-
border_dist = float(distance)
|
|
840
|
-
elif distance.isnumeric():
|
|
841
|
-
border_dist = float(distance)
|
|
842
|
-
|
|
843
|
-
print(border_dist)
|
|
844
|
-
border_label = contour_of_instance_segmentation(self.test_mask, border_dist)
|
|
845
|
-
|
|
846
|
-
self.fig_contour, self.ax_contour = plt.subplots(figsize=(5, 5))
|
|
847
|
-
self.imshow_contour = FigureCanvas(self.fig_contour, title="Contour measurement", interactive=True)
|
|
848
|
-
self.ax_contour.clear()
|
|
849
|
-
self.im_contour = self.ax_contour.imshow(self.test_frame[:, :, 0], cmap='gray')
|
|
850
|
-
self.im_mask = self.ax_contour.imshow(np.ma.masked_where(border_label == 0, border_label),
|
|
851
|
-
cmap='viridis', interpolation='none')
|
|
852
|
-
self.ax_contour.set_xticks([])
|
|
853
|
-
self.ax_contour.set_yticks([])
|
|
854
|
-
self.ax_contour.set_title(border_dist)
|
|
855
|
-
self.fig_contour.set_facecolor('none') # or 'None'
|
|
856
|
-
self.fig_contour.canvas.setStyleSheet("background-color: transparent;")
|
|
857
|
-
self.imshow_contour.canvas.draw()
|
|
858
|
-
|
|
859
|
-
self.imshow_contour.layout.setContentsMargins(30, 30, 30, 30)
|
|
860
|
-
self.channel_hbox_contour = QHBoxLayout()
|
|
861
|
-
self.channel_hbox_contour.addWidget(QLabel('channel: '), 10)
|
|
862
|
-
self.channel_cb_contour = QComboBox()
|
|
863
|
-
self.channel_cb_contour.addItems(self.channel_names)
|
|
864
|
-
self.channel_cb_contour.currentIndexChanged.connect(self.switch_channel_contour)
|
|
865
|
-
self.channel_hbox_contour.addWidget(self.channel_cb_contour, 90)
|
|
866
|
-
self.imshow_contour.layout.addLayout(self.channel_hbox_contour)
|
|
867
|
-
|
|
868
|
-
self.contrast_hbox_contour = QHBoxLayout()
|
|
869
|
-
self.contrast_hbox_contour.addWidget(QLabel('contrast: '), 10)
|
|
870
|
-
self.contrast_slider_contour = QLabeledDoubleRangeSlider()
|
|
871
|
-
self.contrast_slider_contour.setSingleStep(0.00001)
|
|
872
|
-
self.contrast_slider_contour.setTickInterval(0.00001)
|
|
873
|
-
self.contrast_slider_contour.setOrientation(1)
|
|
874
|
-
self.contrast_slider_contour.setRange(np.amin(self.test_frame[:, :, 0]),
|
|
875
|
-
np.amax(self.test_frame[:, :, 0]))
|
|
876
|
-
self.contrast_slider_contour.setValue([np.percentile(self.test_frame[:, :, 0].flatten(), 1),
|
|
877
|
-
np.percentile(self.test_frame[:, :, 0].flatten(), 99.99)])
|
|
878
|
-
self.im_contour.set_clim(vmin=np.percentile(self.test_frame[:, :, 0].flatten(), 1),
|
|
879
|
-
vmax=np.percentile(self.test_frame[:, :, 0].flatten(), 99.99))
|
|
880
|
-
self.contrast_slider_contour.valueChanged.connect(self.contrast_im_contour)
|
|
881
|
-
self.contrast_hbox_contour.addWidget(self.contrast_slider_contour, 90)
|
|
882
|
-
self.imshow_contour.layout.addLayout(self.contrast_hbox_contour)
|
|
883
|
-
|
|
884
|
-
self.alpha_mask_hbox_contour = QHBoxLayout()
|
|
885
|
-
self.alpha_mask_hbox_contour.addWidget(QLabel('mask transparency: '), 10)
|
|
886
|
-
self.transparency_slider = QLabeledDoubleSlider()
|
|
887
|
-
self.transparency_slider.setSingleStep(0.001)
|
|
888
|
-
self.transparency_slider.setTickInterval(0.001)
|
|
889
|
-
self.transparency_slider.setOrientation(1)
|
|
890
|
-
self.transparency_slider.setRange(0, 1)
|
|
891
|
-
self.transparency_slider.setValue(0.5)
|
|
892
|
-
self.transparency_slider.valueChanged.connect(self.make_contour_transparent)
|
|
893
|
-
self.alpha_mask_hbox_contour.addWidget(self.transparency_slider, 90)
|
|
894
|
-
self.imshow_contour.layout.addLayout(self.alpha_mask_hbox_contour)
|
|
895
|
-
|
|
896
|
-
self.imshow_contour.show()
|
|
807
|
+
if self.current_stack is not None:
|
|
897
808
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
809
|
+
self.viewer = CellEdgeVisualizer(cell_type=self.mode,
|
|
810
|
+
stack_path=self.current_stack,
|
|
811
|
+
parent_list_widget=self.contours_list.list_widget,
|
|
812
|
+
n_channels=len(self.channel_names),
|
|
813
|
+
target_channel=0,
|
|
814
|
+
window_title='Set an edge measurement',
|
|
815
|
+
channel_cb=True,
|
|
816
|
+
channel_names = self.channel_names,
|
|
817
|
+
PxToUm = 1,
|
|
818
|
+
)
|
|
819
|
+
self.viewer.show()
|
|
907
820
|
|
|
908
821
|
def locate_mask(self):
|
|
909
822
|
|
|
@@ -911,7 +824,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
911
824
|
Load the first mask of the detected movie.
|
|
912
825
|
"""
|
|
913
826
|
|
|
914
|
-
labels_path = str(Path(self.stack0).
|
|
827
|
+
labels_path = str(Path(self.stack0).parent_window.parent_window) + f'/labels_{self.mode}/'
|
|
915
828
|
masks = natsorted(glob(labels_path + '*.tif'))
|
|
916
829
|
if len(masks) == 0:
|
|
917
830
|
print('no mask found')
|
|
@@ -946,207 +859,46 @@ class ConfigMeasurements(QMainWindow):
|
|
|
946
859
|
self.im_mask.set_alpha(value)
|
|
947
860
|
self.fig_contour.canvas.draw_idle()
|
|
948
861
|
|
|
949
|
-
def populate_normalisation_tabs(self):
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
tab1_layout.addWidget(self.tab1_channel_dropdown, 0, 1)
|
|
990
|
-
|
|
991
|
-
tab1_lbl = QLabel()
|
|
992
|
-
tab1_lbl.setText("Outer distance (in px): ")
|
|
993
|
-
tab1_layout.addWidget(tab1_lbl, 1, 0)
|
|
994
|
-
|
|
995
|
-
self.tab1_txt_distance = QLineEdit()
|
|
996
|
-
tab1_layout.addWidget(self.tab1_txt_distance, 1, 1)
|
|
997
|
-
|
|
998
|
-
self.tab1_vis_brdr = QPushButton()
|
|
999
|
-
self.tab1_vis_brdr.setStyleSheet(self.parent.parent.parent.button_select_all)
|
|
1000
|
-
self.tab1_vis_brdr.setIcon(icon(MDI6.eye_outline, color="black"))
|
|
1001
|
-
self.tab1_vis_brdr.setToolTip("View contour")
|
|
1002
|
-
self.tab1_vis_brdr.setIconSize(QSize(20, 20))
|
|
1003
|
-
self.tab1_vis_brdr.clicked.connect(self.view_normalisation_contour)
|
|
1004
|
-
tab1_layout.addWidget(self.tab1_vis_brdr, 1, 2)
|
|
1005
|
-
|
|
1006
|
-
tab1_lbl_type = QLabel()
|
|
1007
|
-
tab1_lbl_type.setText("Type: ")
|
|
1008
|
-
tab1_layout.addWidget(tab1_lbl_type, 2, 0)
|
|
1009
|
-
|
|
1010
|
-
self.tab1_dropdown = QComboBox()
|
|
1011
|
-
self.tab1_dropdown.addItem("Mean")
|
|
1012
|
-
self.tab1_dropdown.addItem("Median")
|
|
1013
|
-
tab1_layout.addWidget(self.tab1_dropdown, 2, 1)
|
|
1014
|
-
|
|
1015
|
-
self.tab1_subtract = QRadioButton('Subtract')
|
|
1016
|
-
self.tab1_divide = QRadioButton('Divide')
|
|
1017
|
-
tab1_layout.addWidget(self.tab1_subtract, 3, 0, alignment=Qt.AlignRight)
|
|
1018
|
-
tab1_layout.addWidget(self.tab1_divide, 3, 1, alignment=Qt.AlignRight)
|
|
1019
|
-
|
|
1020
|
-
tab1_submit = QPushButton()
|
|
1021
|
-
tab1_submit.setText('Add channel')
|
|
1022
|
-
tab1_submit.setStyleSheet(self.parent.parent.parent.button_style_sheet_2)
|
|
1023
|
-
tab1_layout.addWidget(tab1_submit, 4, 0, 1, 3)
|
|
1024
|
-
tab1_submit.clicked.connect(self.add_item_to_list)
|
|
1025
|
-
|
|
1026
|
-
return tab1_layout
|
|
1027
|
-
|
|
1028
|
-
def populate_field_norm_tab(self):
|
|
1029
|
-
|
|
1030
|
-
tab2_layout = QGridLayout(self.tab2)
|
|
1031
|
-
|
|
1032
|
-
channel_lbl = QLabel()
|
|
1033
|
-
channel_lbl.setText("Channel: ")
|
|
1034
|
-
tab2_layout.addWidget(channel_lbl, 0, 0)
|
|
1035
|
-
|
|
1036
|
-
self.tab2_channel_dropdown = QComboBox()
|
|
1037
|
-
self.tab2_channel_dropdown.addItems(self.channel_names)
|
|
1038
|
-
tab2_layout.addWidget(self.tab2_channel_dropdown, 0, 1)
|
|
1039
|
-
|
|
1040
|
-
tab2_lbl = QLabel()
|
|
1041
|
-
tab2_lbl.setText("std threshold: ")
|
|
1042
|
-
tab2_layout.addWidget(tab2_lbl, 1, 0)
|
|
1043
|
-
|
|
1044
|
-
self.tab2_txt_threshold = QLineEdit()
|
|
1045
|
-
tab2_layout.addWidget(self.tab2_txt_threshold, 1, 1)
|
|
1046
|
-
|
|
1047
|
-
self.norm_digit_btn = QPushButton()
|
|
1048
|
-
self.norm_digit_btn.setIcon(icon(MDI6.image_check, color="k"))
|
|
1049
|
-
self.norm_digit_btn.setStyleSheet(self.parent.parent.parent.button_select_all)
|
|
1050
|
-
|
|
1051
|
-
self.norm_digit_btn.clicked.connect(self.show_threshold_visual)
|
|
1052
|
-
tab2_layout.addWidget(self.norm_digit_btn, 1, 2)
|
|
1053
|
-
|
|
1054
|
-
tab2_lbl_type = QLabel()
|
|
1055
|
-
tab2_lbl_type.setText("Type: ")
|
|
1056
|
-
tab2_layout.addWidget(tab2_lbl_type, 2, 0)
|
|
1057
|
-
|
|
1058
|
-
self.tab2_dropdown = QComboBox()
|
|
1059
|
-
self.tab2_dropdown.addItems(["Paraboloid", "Plane"])
|
|
1060
|
-
tab2_layout.addWidget(self.tab2_dropdown, 2, 1)
|
|
1061
|
-
|
|
1062
|
-
self.tab2_subtract = QRadioButton('Subtract')
|
|
1063
|
-
self.tab2_divide = QRadioButton('Divide')
|
|
1064
|
-
self.tab2_sd_btn_group = QButtonGroup(self)
|
|
1065
|
-
self.tab2_sd_btn_group.addButton(self.tab2_subtract)
|
|
1066
|
-
self.tab2_sd_btn_group.addButton(self.tab2_divide)
|
|
1067
|
-
tab2_layout.addWidget(self.tab2_subtract, 3, 0, alignment=Qt.AlignRight)
|
|
1068
|
-
tab2_layout.addWidget(self.tab2_divide, 3, 1, alignment=Qt.AlignRight)
|
|
1069
|
-
|
|
1070
|
-
self.tab2_clip = QRadioButton('Clip')
|
|
1071
|
-
self.tab2_no_clip = QRadioButton("Don't clip")
|
|
1072
|
-
self.tab2_clip_group = QButtonGroup(self)
|
|
1073
|
-
self.tab2_clip_group.addButton(self.tab2_clip)
|
|
1074
|
-
self.tab2_clip_group.addButton(self.tab2_no_clip)
|
|
1075
|
-
self.tab2_clip.setEnabled(False)
|
|
1076
|
-
self.tab2_no_clip.setEnabled(False)
|
|
1077
|
-
tab2_layout.addWidget(self.tab2_clip, 4, 0, alignment=Qt.AlignLeft)
|
|
1078
|
-
tab2_layout.addWidget(self.tab2_no_clip, 4, 1, alignment=Qt.AlignLeft)
|
|
1079
|
-
self.tab2_subtract.toggled.connect(self.show_clipping_options)
|
|
1080
|
-
self.tab2_divide.toggled.connect(self.show_clipping_options)
|
|
1081
|
-
|
|
1082
|
-
self.view_norm_btn = QPushButton("")
|
|
1083
|
-
self.view_norm_btn.setStyleSheet(self.parent.parent.parent.button_select_all)
|
|
1084
|
-
self.view_norm_btn.setIcon(icon(MDI6.eye_outline, color="black"))
|
|
1085
|
-
self.view_norm_btn.setToolTip("View corrected image")
|
|
1086
|
-
self.view_norm_btn.setIconSize(QSize(20, 20))
|
|
1087
|
-
self.view_norm_btn.clicked.connect(self.preview_normalisation)
|
|
1088
|
-
tab2_layout.addWidget(self.view_norm_btn, 4, 2)
|
|
1089
|
-
|
|
1090
|
-
tab2_submit = QPushButton()
|
|
1091
|
-
tab2_submit.setText('Add channel')
|
|
1092
|
-
tab2_submit.setStyleSheet(self.parent.parent.parent.button_style_sheet_2)
|
|
1093
|
-
tab2_layout.addWidget(tab2_submit, 5, 0, 1, 3)
|
|
1094
|
-
tab2_submit.clicked.connect(self.add_item_to_list)
|
|
1095
|
-
|
|
1096
|
-
return tab2_layout
|
|
1097
|
-
|
|
1098
|
-
def show_threshold_visual(self):
|
|
1099
|
-
min_threshold = self.tab2_txt_threshold.text()
|
|
1100
|
-
if min_threshold == "":
|
|
1101
|
-
min_threshold = 0
|
|
1102
|
-
current_channel = self.tab2_channel_dropdown.currentIndex()
|
|
1103
|
-
self.threshold_visual = ThresholdNormalisation(min_threshold=float(min_threshold),
|
|
1104
|
-
current_channel=current_channel, parent=self)
|
|
1105
|
-
|
|
1106
|
-
def show_clipping_options(self):
|
|
1107
|
-
if self.tab2_subtract.isChecked():
|
|
1108
|
-
for button in self.tab2_clip_group.buttons():
|
|
1109
|
-
button.setEnabled(True)
|
|
1110
|
-
if self.tab2_divide.isChecked():
|
|
1111
|
-
self.tab2_clip_group.setExclusive(False)
|
|
1112
|
-
for button in self.tab2_clip_group.buttons():
|
|
1113
|
-
button.setChecked(False)
|
|
1114
|
-
button.setEnabled(False)
|
|
1115
|
-
self.tab2_clip_group.setExclusive(True)
|
|
1116
|
-
|
|
1117
|
-
def add_item_to_list(self):
|
|
1118
|
-
check = self.check_the_information()
|
|
1119
|
-
if check is True:
|
|
1120
|
-
|
|
1121
|
-
if self.tabs.currentIndex() == 0:
|
|
1122
|
-
|
|
1123
|
-
norm_params = {"target channel": self.tab1_channel_dropdown.currentText(), "mode": "local",
|
|
1124
|
-
"distance": self.tab1_txt_distance.text(),
|
|
1125
|
-
"type": self.tab1_dropdown.currentText()}
|
|
1126
|
-
if self.tab1_subtract.isChecked():
|
|
1127
|
-
norm_params["operation"] = "Subtract"
|
|
1128
|
-
else:
|
|
1129
|
-
norm_params["operation"] = "Divide"
|
|
1130
|
-
elif self.tabs.currentIndex() == 1:
|
|
1131
|
-
norm_params = {"target channel": self.tab2_channel_dropdown.currentText(), "mode": "field",
|
|
1132
|
-
"threshold": self.tab2_txt_threshold.text(),
|
|
1133
|
-
"type": self.tab2_dropdown.currentText()}
|
|
1134
|
-
if self.tab2_subtract.isChecked():
|
|
1135
|
-
norm_params["operation"] = "Subtract"
|
|
1136
|
-
if self.tab2_clip.isChecked():
|
|
1137
|
-
norm_params["clip"] = True
|
|
1138
|
-
else:
|
|
1139
|
-
norm_params["clip"] = False
|
|
1140
|
-
elif self.tab2_divide.isChecked():
|
|
1141
|
-
norm_params["operation"] = "Divide"
|
|
1142
|
-
|
|
1143
|
-
self.background_correction.append(norm_params)
|
|
1144
|
-
normalisation_description = ""
|
|
1145
|
-
for index, (key, value) in enumerate(norm_params.items()):
|
|
1146
|
-
if index > 0:
|
|
1147
|
-
normalisation_description += ", "
|
|
1148
|
-
normalisation_description += str(key) + " : " + str(value)
|
|
1149
|
-
self.normalisation_list.addItem(normalisation_description)
|
|
862
|
+
# def populate_normalisation_tabs(self):
|
|
863
|
+
|
|
864
|
+
# """
|
|
865
|
+
# Multi-tab options to perform background correction before measurements.
|
|
866
|
+
# """
|
|
867
|
+
|
|
868
|
+
# layout = QVBoxLayout(self.normalisation_frame)
|
|
869
|
+
|
|
870
|
+
# self.normalisation_lbl = QLabel("BACKGROUND CORRECTION")
|
|
871
|
+
# self.normalisation_lbl.setStyleSheet("""
|
|
872
|
+
# font-weight: bold;
|
|
873
|
+
# padding: 0px;
|
|
874
|
+
# """)
|
|
875
|
+
# layout.addWidget(self.normalisation_lbl, alignment=Qt.AlignCenter)
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
# self.tabs = QTabWidget()
|
|
879
|
+
# self.tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
880
|
+
|
|
881
|
+
# self.tab1, self.tab2 = QWidget(), QWidget()
|
|
882
|
+
# self.normalisation_list = QListWidget()
|
|
883
|
+
# self.tabs.addTab(self.tab1, 'Local')
|
|
884
|
+
# self.tabs.addTab(self.tab2, 'Field')
|
|
885
|
+
# self.local_correction_layout = LocalCorrectionLayout(self, self.tab1)
|
|
886
|
+
# self.fit_correction_layout = BackgroundFitCorrectionLayout(self, self.tab2)
|
|
887
|
+
# layout.addWidget(self.tabs)
|
|
888
|
+
|
|
889
|
+
# self.norm_list_lbl = QLabel('Background correction to perform:')
|
|
890
|
+
# hbox = QHBoxLayout()
|
|
891
|
+
# hbox.addWidget(self.norm_list_lbl)
|
|
892
|
+
# self.del_norm_btn = QPushButton("")
|
|
893
|
+
# self.del_norm_btn.setStyleSheet(self.button_select_all)
|
|
894
|
+
# self.del_norm_btn.setIcon(icon(MDI6.trash_can, color="black"))
|
|
895
|
+
# self.del_norm_btn.setToolTip("Remove background correction")
|
|
896
|
+
# self.del_norm_btn.setIconSize(QSize(20, 20))
|
|
897
|
+
# hbox.addWidget(self.del_norm_btn, alignment=Qt.AlignRight)
|
|
898
|
+
# layout.addLayout(hbox)
|
|
899
|
+
# self.del_norm_btn.clicked.connect(self.remove_item_from_list)
|
|
900
|
+
# layout.addWidget(self.normalisation_list)
|
|
901
|
+
|
|
1150
902
|
|
|
1151
903
|
def remove_item_from_list(self):
|
|
1152
904
|
current_item = self.normalisation_list.currentRow()
|
|
@@ -1155,6 +907,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
1155
907
|
self.normalisation_list.takeItem(current_item)
|
|
1156
908
|
|
|
1157
909
|
def check_the_information(self):
|
|
910
|
+
|
|
1158
911
|
if self.tabs.currentIndex() == 0:
|
|
1159
912
|
if self.background_correction is None:
|
|
1160
913
|
self.background_correction = []
|
|
@@ -1167,38 +920,6 @@ class ConfigMeasurements(QMainWindow):
|
|
|
1167
920
|
self.background_correction .remove(normalisation_opt)
|
|
1168
921
|
self.normalisation_list.takeItem(index)
|
|
1169
922
|
return True
|
|
1170
|
-
if self.tab1_txt_distance.text() == "":
|
|
1171
|
-
self.display_message_box('provide the outer distance')
|
|
1172
|
-
return False
|
|
1173
|
-
if not self.tab1_subtract.isChecked() and not self.tab1_divide.isChecked():
|
|
1174
|
-
self.display_message_box('choose the operation')
|
|
1175
|
-
return False
|
|
1176
|
-
else:
|
|
1177
|
-
return True
|
|
1178
|
-
|
|
1179
|
-
elif self.tabs.currentIndex() == 1:
|
|
1180
|
-
if self.background_correction is None:
|
|
1181
|
-
self.background_correction = []
|
|
1182
|
-
for index, normalisation_opt in enumerate(self.background_correction ):
|
|
1183
|
-
if self.tab2_channel_dropdown.currentText() in normalisation_opt['target channel']:
|
|
1184
|
-
result = self.channel_already_in_list()
|
|
1185
|
-
if result != QMessageBox.Yes:
|
|
1186
|
-
return False
|
|
1187
|
-
else:
|
|
1188
|
-
self.background_correction .remove(normalisation_opt)
|
|
1189
|
-
self.normalisation_list.takeItem(index)
|
|
1190
|
-
return True
|
|
1191
|
-
if self.tab2_txt_threshold.text() == "":
|
|
1192
|
-
self.display_message_box('provide the threshold')
|
|
1193
|
-
return False
|
|
1194
|
-
elif not self.tab2_divide.isChecked() and not self.tab2_subtract.isChecked():
|
|
1195
|
-
self.display_message_box('choose subtraction or division')
|
|
1196
|
-
return False
|
|
1197
|
-
elif self.tab2_subtract.isChecked():
|
|
1198
|
-
if not self.tab2_clip.isChecked() and not self.tab2_no_clip.isChecked():
|
|
1199
|
-
self.display_message_box('provide the clipping mode')
|
|
1200
|
-
return False
|
|
1201
|
-
return True
|
|
1202
923
|
|
|
1203
924
|
def display_message_box(self, missing_info):
|
|
1204
925
|
QMessageBox.about(self, "Message Box Title", "Please " + missing_info + " for background correction")
|
|
@@ -1214,46 +935,46 @@ class ConfigMeasurements(QMainWindow):
|
|
|
1214
935
|
def fun(self, x, y):
|
|
1215
936
|
return x ** 2 + y
|
|
1216
937
|
|
|
1217
|
-
def preview_normalisation(self):
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
938
|
+
# def preview_normalisation(self):
|
|
939
|
+
# plt.close('all')
|
|
940
|
+
# plt.figure("Intensity Profiles",figsize=(10, 5))
|
|
941
|
+
# self.locate_image()
|
|
942
|
+
# diagonal_length = min(self.test_frame[:, :, self.tab2_channel_dropdown.currentIndex()].shape[0], self.test_frame[:, :, self.tab2_channel_dropdown.currentIndex()].shape[1])
|
|
943
|
+
# if self.tab2_subtract.isChecked():
|
|
944
|
+
# norm_operation='Subtract'
|
|
945
|
+
# else:
|
|
946
|
+
# norm_operation='Divide'
|
|
947
|
+
# normalised, bg_fit = field_normalisation(self.test_frame[:, :, self.tab2_channel_dropdown.currentIndex()],
|
|
948
|
+
# threshold=self.tab2_txt_threshold.text(),
|
|
949
|
+
# normalisation_operation=norm_operation,
|
|
950
|
+
# clip=self.tab2_clip.isChecked(),
|
|
951
|
+
# mode=self.tab2_dropdown.currentText())
|
|
952
|
+
# diagonal_original = [self.test_frame[:, :, self.tab2_channel_dropdown.currentIndex()][i, i] for i in
|
|
953
|
+
# range(diagonal_length)]
|
|
954
|
+
# diagonal_corrected = [normalised[i, i] for i in range(diagonal_length)]
|
|
955
|
+
# diagonal_indices = np.arange(diagonal_length)
|
|
956
|
+
|
|
957
|
+
# plt.subplot(1, 2, 1)
|
|
958
|
+
# plt.plot(diagonal_indices, diagonal_original, color='black', linewidth=0.2) # Adjust linewidth here
|
|
959
|
+
# plt.title('Original Image')
|
|
960
|
+
# plt.xlabel('Pixel Index along Diagonal')
|
|
961
|
+
# plt.ylabel('Intensity')
|
|
962
|
+
|
|
963
|
+
# plt.subplot(1, 2, 2)
|
|
964
|
+
# plt.plot(diagonal_indices, diagonal_corrected, color='black', linewidth=0.2) # Adjust linewidth here
|
|
965
|
+
# plt.title('Corrected Image')
|
|
966
|
+
# plt.xlabel('Pixel Index along Diagonal')
|
|
967
|
+
# plt.ylabel('Intensity')
|
|
968
|
+
|
|
969
|
+
# plt.tight_layout()
|
|
970
|
+
# plt.show()
|
|
971
|
+
|
|
972
|
+
# self.fig, self.ax = plt.subplots()
|
|
973
|
+
# self.normalised_img = FigureCanvas(self.fig, "Corrected background image preview")
|
|
974
|
+
# self.ax.clear()
|
|
975
|
+
# self.ax.imshow(normalised, cmap='gray')
|
|
976
|
+
# self.normalised_img.canvas.draw()
|
|
977
|
+
# self.normalised_img.show()
|
|
1257
978
|
|
|
1258
979
|
def view_normalisation_contour(self):
|
|
1259
980
|
|
|
@@ -1262,67 +983,27 @@ class ConfigMeasurements(QMainWindow):
|
|
|
1262
983
|
|
|
1263
984
|
"""
|
|
1264
985
|
|
|
1265
|
-
if self.parent.parent.position_list.currentText() == '*':
|
|
1266
|
-
msgBox = QMessageBox()
|
|
1267
|
-
msgBox.setIcon(QMessageBox.Warning)
|
|
1268
|
-
msgBox.setText("Please select a single position to visualize the border selection.")
|
|
1269
|
-
msgBox.setWindowTitle("Warning")
|
|
1270
|
-
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
1271
|
-
returnValue = msgBox.exec()
|
|
1272
|
-
if returnValue == QMessageBox.Ok:
|
|
1273
|
-
return None
|
|
1274
|
-
else:
|
|
1275
|
-
return None
|
|
1276
|
-
|
|
1277
986
|
self.locate_image()
|
|
1278
987
|
|
|
1279
|
-
self.
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
988
|
+
if self.current_stack is not None:
|
|
989
|
+
|
|
990
|
+
self.viewer = CellEdgeVisualizer(cell_type=self.mode,
|
|
991
|
+
stack_path=self.current_stack,
|
|
992
|
+
parent_le = self.tab1_txt_distance,
|
|
993
|
+
n_channels=len(self.channel_names),
|
|
994
|
+
target_channel=self.tab1_channel_dropdown.currentIndex(),
|
|
995
|
+
edge_range = (0,30),
|
|
996
|
+
initial_edge= self.tab1_txt_distance.get_threshold(),
|
|
997
|
+
invert=True,
|
|
998
|
+
window_title='Set an edge distance to estimate local intensity',
|
|
999
|
+
channel_cb=False,
|
|
1000
|
+
PxToUm = 1,
|
|
1001
|
+
)
|
|
1002
|
+
self.viewer.show()
|
|
1291
1003
|
|
|
1292
|
-
if (self.test_frame is not None) and (self.test_mask is not None):
|
|
1293
|
-
contour = float(self.tab1_txt_distance.text())
|
|
1294
|
-
contour = contour * (-1)
|
|
1295
|
-
border_label = contour_of_instance_segmentation(self.test_mask, contour)
|
|
1296
|
-
|
|
1297
|
-
self.fig_contour, self.ax_contour = plt.subplots(figsize=(5, 5))
|
|
1298
|
-
self.imshow_contour = FigureCanvas(self.fig_contour, title="Contour measurement", interactive=True)
|
|
1299
|
-
self.ax_contour.clear()
|
|
1300
|
-
self.im_contour = self.ax_contour.imshow(self.test_frame[:, :, self.tab1_channel_dropdown.currentIndex()],
|
|
1301
|
-
cmap='gray')
|
|
1302
|
-
self.im_mask = self.ax_contour.imshow(np.ma.masked_where(border_label == 0, border_label),
|
|
1303
|
-
cmap='viridis', interpolation='none')
|
|
1304
|
-
self.ax_contour.set_xticks([])
|
|
1305
|
-
self.ax_contour.set_yticks([])
|
|
1306
|
-
self.ax_contour.set_title(contour * (-1))
|
|
1307
|
-
self.fig_contour.set_facecolor('none') # or 'None'
|
|
1308
|
-
self.fig_contour.canvas.setStyleSheet("background-color: transparent;")
|
|
1309
|
-
self.imshow_contour.canvas.draw()
|
|
1310
|
-
|
|
1311
|
-
self.imshow_contour.show()
|
|
1312
|
-
|
|
1313
|
-
# def enable_step_size(self):
|
|
1314
|
-
# if self.radial_intensity_btn.isChecked():
|
|
1315
|
-
# self.step_lbl.setEnabled(True)
|
|
1316
|
-
# self.step_size.setEnabled(True)
|
|
1317
|
-
# for checkbox in self.channel_chechkboxes:
|
|
1318
|
-
# checkbox.setEnabled(True)
|
|
1319
|
-
# else:
|
|
1320
|
-
# self.step_lbl.setEnabled(False)
|
|
1321
|
-
# self.step_size.setEnabled(False)
|
|
1322
|
-
# for checkbox in self.channel_chechkboxes:
|
|
1323
|
-
# checkbox.setEnabled(False)
|
|
1324
1004
|
|
|
1325
1005
|
def populate_spot_detection(self):
|
|
1006
|
+
|
|
1326
1007
|
layout = QGridLayout(self.spot_detection_frame)
|
|
1327
1008
|
self.spot_detection_lbl = QLabel("SPOT DETECTION")
|
|
1328
1009
|
self.spot_detection_lbl.setStyleSheet("""font-weight: bold;padding: 0px;""")
|
|
@@ -1353,7 +1034,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
1353
1034
|
layout.addWidget(self.threshold_value, 4, 1)
|
|
1354
1035
|
self.preview_spot = QPushButton('Preview')
|
|
1355
1036
|
self.preview_spot.clicked.connect(self.spot_preview)
|
|
1356
|
-
self.preview_spot.setStyleSheet(self.
|
|
1037
|
+
self.preview_spot.setStyleSheet(self.button_style_sheet_2)
|
|
1357
1038
|
layout.addWidget(self.preview_spot, 5, 0, 1, 2)
|
|
1358
1039
|
self.spot_channel.setEnabled(False)
|
|
1359
1040
|
self.spot_channel_lbl.setEnabled(False)
|
|
@@ -1379,7 +1060,7 @@ class ConfigMeasurements(QMainWindow):
|
|
|
1379
1060
|
self.locate_mask()
|
|
1380
1061
|
if self.test_mask is not None:
|
|
1381
1062
|
self.spot_visual = ThresholdSpot(current_channel=self.spot_channel.currentIndex(), img=self.test_frame,
|
|
1382
|
-
mask=self.test_mask,
|
|
1063
|
+
mask=self.test_mask, parent_window=self)
|
|
1383
1064
|
# for dictionary in self.background_correction:
|
|
1384
1065
|
# if self.spot_channel.currentText() in dictionary['target channel']:
|
|
1385
1066
|
# if dictionary['mode'] == 'field':
|