celldetective 1.3.9.post5__py3-none-any.whl → 1.4.1__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/__init__.py +0 -3
- celldetective/_version.py +1 -1
- celldetective/events.py +2 -4
- celldetective/exceptions.py +11 -0
- celldetective/extra_properties.py +132 -0
- celldetective/filters.py +7 -1
- celldetective/gui/InitWindow.py +37 -46
- celldetective/gui/__init__.py +3 -9
- celldetective/gui/about.py +19 -15
- celldetective/gui/analyze_block.py +34 -19
- celldetective/gui/base_annotator.py +786 -0
- celldetective/gui/base_components.py +23 -0
- celldetective/gui/classifier_widget.py +86 -94
- celldetective/gui/configure_new_exp.py +163 -46
- celldetective/gui/control_panel.py +76 -146
- celldetective/gui/{signal_annotator.py → event_annotator.py} +533 -1438
- celldetective/gui/generic_signal_plot.py +11 -13
- celldetective/gui/gui_utils.py +54 -23
- celldetective/gui/help/neighborhood.json +2 -2
- celldetective/gui/json_readers.py +5 -4
- celldetective/gui/layouts.py +265 -31
- celldetective/gui/{signal_annotator2.py → pair_event_annotator.py} +433 -635
- celldetective/gui/plot_measurements.py +21 -17
- celldetective/gui/plot_signals_ui.py +125 -72
- celldetective/gui/process_block.py +283 -188
- celldetective/gui/processes/compute_neighborhood.py +594 -0
- celldetective/gui/processes/downloader.py +37 -34
- celldetective/gui/processes/measure_cells.py +19 -8
- celldetective/gui/processes/segment_cells.py +47 -11
- celldetective/gui/processes/track_cells.py +18 -13
- celldetective/gui/seg_model_loader.py +21 -62
- celldetective/gui/settings/__init__.py +7 -0
- celldetective/gui/settings/_settings_base.py +70 -0
- celldetective/gui/{retrain_signal_model_options.py → settings/_settings_event_model_training.py} +54 -109
- celldetective/gui/{measurement_options.py → settings/_settings_measurements.py} +54 -92
- celldetective/gui/{neighborhood_options.py → settings/_settings_neighborhood.py} +10 -13
- celldetective/gui/settings/_settings_segmentation.py +49 -0
- celldetective/gui/{retrain_segmentation_model_options.py → settings/_settings_segmentation_model_training.py} +38 -92
- celldetective/gui/{signal_annotator_options.py → settings/_settings_signal_annotator.py} +78 -103
- celldetective/gui/{btrack_options.py → settings/_settings_tracking.py} +85 -116
- celldetective/gui/styles.py +2 -1
- celldetective/gui/survival_ui.py +49 -95
- celldetective/gui/tableUI.py +53 -25
- celldetective/gui/table_ops/__init__.py +0 -0
- celldetective/gui/table_ops/merge_groups.py +118 -0
- celldetective/gui/thresholds_gui.py +617 -1221
- celldetective/gui/viewers.py +107 -42
- celldetective/gui/workers.py +8 -4
- celldetective/io.py +137 -57
- celldetective/links/zenodo.json +145 -144
- celldetective/measure.py +94 -53
- celldetective/neighborhood.py +342 -268
- celldetective/preprocessing.py +56 -35
- celldetective/regionprops/_regionprops.py +16 -5
- celldetective/relative_measurements.py +50 -29
- celldetective/scripts/analyze_signals.py +4 -1
- celldetective/scripts/measure_cells.py +5 -5
- celldetective/scripts/measure_relative.py +20 -12
- celldetective/scripts/segment_cells.py +4 -10
- celldetective/scripts/segment_cells_thresholds.py +3 -3
- celldetective/scripts/track_cells.py +10 -8
- celldetective/scripts/train_segmentation_model.py +18 -6
- celldetective/signals.py +29 -14
- celldetective/tracking.py +14 -3
- celldetective/utils.py +91 -62
- {celldetective-1.3.9.post5.dist-info → celldetective-1.4.1.dist-info}/METADATA +24 -16
- celldetective-1.4.1.dist-info/RECORD +123 -0
- {celldetective-1.3.9.post5.dist-info → celldetective-1.4.1.dist-info}/WHEEL +1 -1
- tests/gui/__init__.py +0 -0
- tests/gui/test_new_project.py +228 -0
- tests/gui/test_project.py +99 -0
- tests/test_preprocessing.py +2 -2
- celldetective/models/segmentation_effectors/ricm_bf_all_last/config_input.json +0 -79
- celldetective/models/segmentation_effectors/ricm_bf_all_last/ricm_bf_all_last +0 -0
- celldetective/models/segmentation_effectors/ricm_bf_all_last/training_instructions.json +0 -37
- celldetective/models/segmentation_effectors/test-transfer/config_input.json +0 -39
- celldetective/models/segmentation_effectors/test-transfer/test-transfer +0 -0
- celldetective/models/signal_detection/NucCond/classification_loss.png +0 -0
- celldetective/models/signal_detection/NucCond/classifier.h5 +0 -0
- celldetective/models/signal_detection/NucCond/config_input.json +0 -1
- celldetective/models/signal_detection/NucCond/log_classifier.csv +0 -126
- celldetective/models/signal_detection/NucCond/log_regressor.csv +0 -282
- celldetective/models/signal_detection/NucCond/regression_loss.png +0 -0
- celldetective/models/signal_detection/NucCond/regressor.h5 +0 -0
- celldetective/models/signal_detection/NucCond/scores.npy +0 -0
- celldetective/models/signal_detection/NucCond/test_confusion_matrix.png +0 -0
- celldetective/models/signal_detection/NucCond/test_regression.png +0 -0
- celldetective/models/signal_detection/NucCond/validation_confusion_matrix.png +0 -0
- celldetective/models/signal_detection/NucCond/validation_regression.png +0 -0
- celldetective-1.3.9.post5.dist-info/RECORD +0 -129
- tests/test_qt.py +0 -103
- {celldetective-1.3.9.post5.dist-info → celldetective-1.4.1.dist-info}/entry_points.txt +0 -0
- {celldetective-1.3.9.post5.dist-info → celldetective-1.4.1.dist-info/licenses}/LICENSE +0 -0
- {celldetective-1.3.9.post5.dist-info → celldetective-1.4.1.dist-info}/top_level.txt +0 -0
celldetective/gui/viewers.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import numpy as np
|
|
2
1
|
from celldetective.io import auto_load_number_of_frames, load_frames
|
|
3
2
|
from celldetective.filters import *
|
|
4
3
|
from celldetective.segmentation import filter_image, threshold_image
|
|
5
4
|
from celldetective.measure import contour_of_instance_segmentation, extract_blobs_in_image
|
|
6
|
-
from celldetective.utils import _get_img_num_per_channel, estimate_unreliable_edge
|
|
5
|
+
from celldetective.utils import _get_img_num_per_channel, estimate_unreliable_edge, is_integer_array
|
|
7
6
|
from tifffile import imread
|
|
8
7
|
import matplotlib.pyplot as plt
|
|
9
8
|
from pathlib import Path
|
|
@@ -11,20 +10,19 @@ from natsort import natsorted
|
|
|
11
10
|
from glob import glob
|
|
12
11
|
import os
|
|
13
12
|
|
|
14
|
-
from PyQt5.QtWidgets import
|
|
13
|
+
from PyQt5.QtWidgets import QHBoxLayout, QMessageBox, QPushButton, QLabel, QComboBox, QLineEdit, QListWidget, QShortcut
|
|
15
14
|
from PyQt5.QtCore import Qt, QSize
|
|
16
15
|
from PyQt5.QtGui import QKeySequence, QDoubleValidator
|
|
17
|
-
from celldetective.gui.gui_utils import FigureCanvas,
|
|
18
|
-
from celldetective.gui import
|
|
16
|
+
from celldetective.gui.gui_utils import FigureCanvas, QuickSliderLayout, QHSeperationLine, ThresholdLineEdit, PreprocessingLayout2
|
|
17
|
+
from celldetective.gui import CelldetectiveWidget
|
|
19
18
|
from superqt import QLabeledDoubleSlider, QLabeledSlider, QLabeledDoubleRangeSlider
|
|
20
19
|
from superqt.fonticon import icon
|
|
21
20
|
from fonticon_mdi6 import MDI6
|
|
22
21
|
from matplotlib_scalebar.scalebar import ScaleBar
|
|
23
22
|
import gc
|
|
24
|
-
from celldetective.utils import mask_edges
|
|
25
23
|
from scipy.ndimage import shift
|
|
26
24
|
|
|
27
|
-
class StackVisualizer(
|
|
25
|
+
class StackVisualizer(CelldetectiveWidget):
|
|
28
26
|
|
|
29
27
|
"""
|
|
30
28
|
A widget for visualizing image stacks with interactive sliders and channel selection.
|
|
@@ -92,8 +90,7 @@ class StackVisualizer(QWidget, Styles):
|
|
|
92
90
|
self.generate_frame_slider()
|
|
93
91
|
|
|
94
92
|
self.canvas.layout.setContentsMargins(15,15,15,30)
|
|
95
|
-
self
|
|
96
|
-
center_window(self)
|
|
93
|
+
#center_window(self)
|
|
97
94
|
|
|
98
95
|
def show(self):
|
|
99
96
|
# Display the widget
|
|
@@ -136,6 +133,7 @@ class StackVisualizer(QWidget, Styles):
|
|
|
136
133
|
self.stack_path,
|
|
137
134
|
normalize_input=False).astype(float)[:,:,0]
|
|
138
135
|
|
|
136
|
+
|
|
139
137
|
def generate_figure_canvas(self):
|
|
140
138
|
# Generate the figure canvas for displaying images
|
|
141
139
|
|
|
@@ -187,6 +185,16 @@ class StackVisualizer(QWidget, Styles):
|
|
|
187
185
|
channel_layout.addWidget(self.channels_cb, 75)
|
|
188
186
|
self.canvas.layout.addLayout(channel_layout)
|
|
189
187
|
|
|
188
|
+
def set_contrast_decimals(self):
|
|
189
|
+
if is_integer_array(self.init_frame):
|
|
190
|
+
self.contrast_slider.setDecimals(0)
|
|
191
|
+
self.contrast_slider.setSingleStep(1.0)
|
|
192
|
+
self.contrast_slider.setTickInterval(1.0)
|
|
193
|
+
else:
|
|
194
|
+
self.contrast_slider.setDecimals(3)
|
|
195
|
+
self.contrast_slider.setSingleStep(1.0E-03)
|
|
196
|
+
self.contrast_slider.setTickInterval(1.0E-03)
|
|
197
|
+
|
|
190
198
|
def generate_contrast_slider(self):
|
|
191
199
|
# Generate the contrast slider if enabled
|
|
192
200
|
|
|
@@ -197,15 +205,15 @@ class StackVisualizer(QWidget, Styles):
|
|
|
197
205
|
slider_initial_value=[np.nanpercentile(self.init_frame, 0.1),np.nanpercentile(self.init_frame, 99.99)],
|
|
198
206
|
slider_range=(np.nanmin(self.init_frame),np.nanmax(self.init_frame)),
|
|
199
207
|
decimal_option=True,
|
|
200
|
-
precision=
|
|
208
|
+
precision=2,
|
|
201
209
|
)
|
|
210
|
+
self.set_contrast_decimals()
|
|
211
|
+
|
|
202
212
|
contrast_layout.setContentsMargins(15,0,15,0)
|
|
203
213
|
self.im.set_clim(vmin=np.nanpercentile(self.init_frame, 0.1),vmax=np.nanpercentile(self.init_frame, 99.99))
|
|
204
214
|
self.contrast_slider.valueChanged.connect(self.change_contrast)
|
|
205
215
|
self.canvas.layout.addLayout(contrast_layout)
|
|
206
216
|
|
|
207
|
-
|
|
208
|
-
|
|
209
217
|
def generate_frame_slider(self):
|
|
210
218
|
# Generate the frame slider if enabled
|
|
211
219
|
|
|
@@ -250,6 +258,8 @@ class StackVisualizer(QWidget, Styles):
|
|
|
250
258
|
self.channel_trigger = False
|
|
251
259
|
self.init_contrast = False
|
|
252
260
|
|
|
261
|
+
self.set_contrast_decimals()
|
|
262
|
+
|
|
253
263
|
def change_frame_from_channel_switch(self, value):
|
|
254
264
|
|
|
255
265
|
self.channel_trigger = True
|
|
@@ -275,15 +285,17 @@ class StackVisualizer(QWidget, Styles):
|
|
|
275
285
|
self.im.set_data(self.init_frame)
|
|
276
286
|
|
|
277
287
|
if self.init_contrast:
|
|
278
|
-
self.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
self.contrast_slider.
|
|
288
|
+
imgs = np.array([self.init_frame,self.last_frame])
|
|
289
|
+
vmin = np.nanpercentile(imgs.flatten(), 1.0)
|
|
290
|
+
vmax = np.nanpercentile(imgs.flatten(), 99.99)
|
|
291
|
+
self.contrast_slider.setRange(np.nanmin(imgs),np.nanmax(imgs))
|
|
292
|
+
self.contrast_slider.setValue((vmin,vmax))
|
|
293
|
+
self.im.set_clim(vmin,vmax)
|
|
282
294
|
|
|
283
295
|
if self.create_contrast_slider:
|
|
284
296
|
self.change_contrast(self.contrast_slider.value())
|
|
285
297
|
|
|
286
|
-
|
|
298
|
+
|
|
287
299
|
def closeEvent(self, event):
|
|
288
300
|
# Event handler for closing the widget
|
|
289
301
|
self.canvas.close()
|
|
@@ -318,16 +330,27 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
318
330
|
with interactive sliders for threshold and mask opacity adjustment.
|
|
319
331
|
"""
|
|
320
332
|
|
|
321
|
-
def __init__(self, preprocessing=None, parent_le=None, initial_threshold=5, initial_mask_alpha=0.5, *args, **kwargs):
|
|
333
|
+
def __init__(self, preprocessing=None, parent_le=None, initial_threshold=5, initial_mask_alpha=0.5, show_opacity_slider=True, show_threshold_slider=True, *args, **kwargs):
|
|
322
334
|
# Initialize the widget and its attributes
|
|
323
335
|
super().__init__(*args, **kwargs)
|
|
324
336
|
self.preprocessing = preprocessing
|
|
325
337
|
self.thresh = initial_threshold
|
|
326
338
|
self.mask_alpha = initial_mask_alpha
|
|
327
339
|
self.parent_le = parent_le
|
|
328
|
-
self.
|
|
329
|
-
self.
|
|
340
|
+
self.show_opacity_slider = show_opacity_slider
|
|
341
|
+
self.show_threshold_slider = show_threshold_slider
|
|
342
|
+
self.thresholded = False
|
|
343
|
+
self.mask = np.zeros_like(self.init_frame)
|
|
344
|
+
self.thresh_min = 0.0
|
|
345
|
+
self.thresh_max = 30.0
|
|
346
|
+
|
|
330
347
|
self.generate_threshold_slider()
|
|
348
|
+
|
|
349
|
+
if self.thresh is not None:
|
|
350
|
+
self.compute_mask(self.thresh)
|
|
351
|
+
|
|
352
|
+
self.generate_mask_imshow()
|
|
353
|
+
self.generate_scatter()
|
|
331
354
|
self.generate_opacity_slider()
|
|
332
355
|
if isinstance(self.parent_le, QLineEdit):
|
|
333
356
|
self.generate_apply_btn()
|
|
@@ -349,23 +372,32 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
349
372
|
self.close()
|
|
350
373
|
|
|
351
374
|
def generate_mask_imshow(self):
|
|
352
|
-
# Generate the mask imshow
|
|
375
|
+
# Generate the mask imshow
|
|
376
|
+
|
|
353
377
|
self.im_mask = self.ax.imshow(np.ma.masked_where(self.mask==0, self.mask), alpha=self.mask_alpha, interpolation='none')
|
|
354
378
|
self.canvas.canvas.draw()
|
|
355
379
|
|
|
380
|
+
def generate_scatter(self):
|
|
381
|
+
self.scat_markers = self.ax.scatter([], [], color="tab:red")
|
|
382
|
+
|
|
356
383
|
def generate_threshold_slider(self):
|
|
357
384
|
# Generate the threshold slider
|
|
358
385
|
self.threshold_slider = QLabeledDoubleSlider()
|
|
386
|
+
if self.thresh is None:
|
|
387
|
+
init_value = 1.0E5
|
|
388
|
+
else:
|
|
389
|
+
init_value = self.thresh
|
|
359
390
|
thresh_layout = QuickSliderLayout(label='Threshold: ',
|
|
360
391
|
slider=self.threshold_slider,
|
|
361
|
-
slider_initial_value=
|
|
362
|
-
slider_range=(
|
|
392
|
+
slider_initial_value=init_value,
|
|
393
|
+
slider_range=(self.thresh_min,np.amax([self.thresh_max, init_value])),
|
|
363
394
|
decimal_option=True,
|
|
364
|
-
precision=
|
|
395
|
+
precision=4,
|
|
365
396
|
)
|
|
366
397
|
thresh_layout.setContentsMargins(15,0,15,0)
|
|
367
398
|
self.threshold_slider.valueChanged.connect(self.change_threshold)
|
|
368
|
-
self.
|
|
399
|
+
if self.show_threshold_slider:
|
|
400
|
+
self.canvas.layout.addLayout(thresh_layout)
|
|
369
401
|
|
|
370
402
|
def generate_opacity_slider(self):
|
|
371
403
|
# Generate the opacity slider for the mask
|
|
@@ -375,11 +407,12 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
375
407
|
slider_initial_value=0.5,
|
|
376
408
|
slider_range=(0,1),
|
|
377
409
|
decimal_option=True,
|
|
378
|
-
precision=
|
|
410
|
+
precision=3,
|
|
379
411
|
)
|
|
380
412
|
opacity_layout.setContentsMargins(15,0,15,0)
|
|
381
413
|
self.opacity_slider.valueChanged.connect(self.change_mask_opacity)
|
|
382
|
-
self.
|
|
414
|
+
if self.show_opacity_slider:
|
|
415
|
+
self.canvas.layout.addLayout(opacity_layout)
|
|
383
416
|
|
|
384
417
|
def change_mask_opacity(self, value):
|
|
385
418
|
# Change the opacity of the mask
|
|
@@ -390,28 +423,61 @@ class ThresholdedStackVisualizer(StackVisualizer):
|
|
|
390
423
|
def change_threshold(self, value):
|
|
391
424
|
# Change the threshold value
|
|
392
425
|
self.thresh = value
|
|
393
|
-
self.
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
426
|
+
if self.thresh is not None:
|
|
427
|
+
self.compute_mask(self.thresh)
|
|
428
|
+
mask = np.ma.masked_where(self.mask == 0, self.mask)
|
|
429
|
+
self.im_mask.set_data(mask)
|
|
430
|
+
self.canvas.canvas.draw_idle()
|
|
397
431
|
|
|
398
432
|
def change_frame(self, value):
|
|
399
|
-
# Change the displayed frame and update the threshold
|
|
433
|
+
# Change the displayed frame and update the threshold
|
|
434
|
+
if self.thresholded:
|
|
435
|
+
self.init_contrast = True
|
|
400
436
|
super().change_frame(value)
|
|
401
437
|
self.change_threshold(self.threshold_slider.value())
|
|
438
|
+
if self.thresholded:
|
|
439
|
+
self.thresholded = False
|
|
440
|
+
self.init_contrast = False
|
|
402
441
|
|
|
403
442
|
def compute_mask(self, threshold_value):
|
|
404
443
|
# Compute the mask based on the threshold value
|
|
405
444
|
self.preprocess_image()
|
|
406
445
|
edge = estimate_unreliable_edge(self.preprocessing)
|
|
407
|
-
|
|
446
|
+
if isinstance(threshold_value, (list,np.ndarray,tuple)):
|
|
447
|
+
self.mask = threshold_image(self.processed_image, threshold_value[0], threshold_value[1], foreground_value=1, fill_holes=True, edge_exclusion=edge).astype(int)
|
|
448
|
+
else:
|
|
449
|
+
self.mask = threshold_image(self.processed_image, threshold_value, np.inf, foreground_value=1, fill_holes=True, edge_exclusion=edge).astype(int)
|
|
408
450
|
|
|
409
451
|
def preprocess_image(self):
|
|
410
452
|
# Preprocess the image before thresholding
|
|
411
453
|
if self.preprocessing is not None:
|
|
412
454
|
|
|
413
455
|
assert isinstance(self.preprocessing, list)
|
|
414
|
-
self.processed_image = filter_image(self.init_frame.copy(),filters=self.preprocessing)
|
|
456
|
+
self.processed_image = filter_image(self.init_frame.copy().astype(float),filters=self.preprocessing)
|
|
457
|
+
min_ = np.amin(self.processed_image)
|
|
458
|
+
max_ = np.amax(self.processed_image)
|
|
459
|
+
|
|
460
|
+
if min_ < self.thresh_min:
|
|
461
|
+
self.thresh_min = min_
|
|
462
|
+
if max_ > self.thresh_max:
|
|
463
|
+
self.thresh_max = max_
|
|
464
|
+
|
|
465
|
+
self.threshold_slider.setRange(self.thresh_min, self.thresh_max)
|
|
466
|
+
|
|
467
|
+
def set_preprocessing(self, activation_protocol):
|
|
468
|
+
|
|
469
|
+
self.preprocessing = activation_protocol
|
|
470
|
+
self.preprocess_image()
|
|
471
|
+
|
|
472
|
+
self.im.set_data(self.processed_image)
|
|
473
|
+
vmin = np.nanpercentile(self.processed_image, 1.0)
|
|
474
|
+
vmax = np.nanpercentile(self.processed_image, 99.99)
|
|
475
|
+
self.contrast_slider.setRange(np.nanmin(self.processed_image),
|
|
476
|
+
np.nanmax(self.processed_image))
|
|
477
|
+
self.contrast_slider.setValue((vmin, vmax))
|
|
478
|
+
self.im.set_clim(vmin,vmax)
|
|
479
|
+
self.canvas.canvas.draw_idle()
|
|
480
|
+
self.thresholded = True
|
|
415
481
|
|
|
416
482
|
|
|
417
483
|
class CellEdgeVisualizer(StackVisualizer):
|
|
@@ -578,7 +644,7 @@ class CellEdgeVisualizer(StackVisualizer):
|
|
|
578
644
|
slider_initial_value=0.5,
|
|
579
645
|
slider_range=(0,1),
|
|
580
646
|
decimal_option=True,
|
|
581
|
-
precision=
|
|
647
|
+
precision=3,
|
|
582
648
|
)
|
|
583
649
|
opacity_layout.setContentsMargins(15,0,15,0)
|
|
584
650
|
self.opacity_slider.valueChanged.connect(self.change_mask_opacity)
|
|
@@ -952,7 +1018,7 @@ class CellSizeViewer(StackVisualizer):
|
|
|
952
1018
|
def generate_circle(self):
|
|
953
1019
|
# Generate the circle for visualization
|
|
954
1020
|
|
|
955
|
-
self.circ = plt.Circle((self.init_frame.shape[0]//2,self.init_frame.shape[1]//2), self.diameter//2, ec="tab:red",fill=False)
|
|
1021
|
+
self.circ = plt.Circle((self.init_frame.shape[0]//2,self.init_frame.shape[1]//2), self.diameter//2 / self.PxToUm, ec="tab:red",fill=False)
|
|
956
1022
|
self.ax.add_patch(self.circ)
|
|
957
1023
|
|
|
958
1024
|
self.ax.callbacks.connect('xlim_changed',self.on_xlims_or_ylims_change)
|
|
@@ -978,7 +1044,7 @@ class CellSizeViewer(StackVisualizer):
|
|
|
978
1044
|
if self.set_radius_in_list:
|
|
979
1045
|
val = int(self.diameter_slider.value()//2)
|
|
980
1046
|
else:
|
|
981
|
-
val = int(self.diameter_slider.value())
|
|
1047
|
+
val = int(self.diameter_slider.value())
|
|
982
1048
|
|
|
983
1049
|
self.parent_list_widget.addItems([str(val)])
|
|
984
1050
|
self.close()
|
|
@@ -1017,7 +1083,7 @@ class CellSizeViewer(StackVisualizer):
|
|
|
1017
1083
|
slider_initial_value=self.diameter,
|
|
1018
1084
|
slider_range=self.diameter_slider_range,
|
|
1019
1085
|
decimal_option=True,
|
|
1020
|
-
precision=
|
|
1086
|
+
precision=5,
|
|
1021
1087
|
)
|
|
1022
1088
|
diameter_layout.setContentsMargins(15,0,15,0)
|
|
1023
1089
|
self.diameter_slider.valueChanged.connect(self.change_diameter)
|
|
@@ -1025,9 +1091,8 @@ class CellSizeViewer(StackVisualizer):
|
|
|
1025
1091
|
|
|
1026
1092
|
def change_diameter(self, value):
|
|
1027
1093
|
# Change the diameter of the circle
|
|
1028
|
-
|
|
1029
1094
|
self.diameter = value
|
|
1030
|
-
self.circ.set_radius(self.diameter//2)
|
|
1095
|
+
self.circ.set_radius(self.diameter//2 / self.PxToUm)
|
|
1031
1096
|
self.canvas.canvas.draw_idle()
|
|
1032
1097
|
|
|
1033
1098
|
|
|
@@ -1080,7 +1145,7 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
1080
1145
|
slider_initial_value=0.5,
|
|
1081
1146
|
slider_range=(0,1.0),
|
|
1082
1147
|
decimal_option=True,
|
|
1083
|
-
precision=
|
|
1148
|
+
precision=5,
|
|
1084
1149
|
)
|
|
1085
1150
|
alpha_layout.setContentsMargins(15,0,15,0)
|
|
1086
1151
|
self.overlay_alpha_slider.valueChanged.connect(self.change_alpha_overlay)
|
|
@@ -1097,7 +1162,7 @@ class ChannelOffsetViewer(StackVisualizer):
|
|
|
1097
1162
|
slider_initial_value=[np.nanpercentile(self.overlay_init_frame, 0.1),np.nanpercentile(self.overlay_init_frame, 99.99)],
|
|
1098
1163
|
slider_range=(np.nanmin(self.overlay_init_frame),np.nanmax(self.overlay_init_frame)),
|
|
1099
1164
|
decimal_option=True,
|
|
1100
|
-
precision=
|
|
1165
|
+
precision=5,
|
|
1101
1166
|
)
|
|
1102
1167
|
contrast_layout.setContentsMargins(15,0,15,0)
|
|
1103
1168
|
self.im_overlay.set_clim(vmin=np.nanpercentile(self.overlay_init_frame, 0.1),vmax=np.nanpercentile(self.overlay_init_frame, 99.99))
|
celldetective/gui/workers.py
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
from multiprocessing import Queue
|
|
2
|
-
from PyQt5.QtWidgets import
|
|
2
|
+
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QHBoxLayout, QLabel, QProgressBar
|
|
3
3
|
from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, QThreadPool, QSize, Qt
|
|
4
|
+
|
|
5
|
+
from celldetective.gui.base_components import CelldetectiveDialog
|
|
4
6
|
from celldetective.gui.gui_utils import center_window
|
|
5
|
-
import time
|
|
6
7
|
import math
|
|
7
8
|
|
|
8
|
-
class ProgressWindow(
|
|
9
|
+
class ProgressWindow(CelldetectiveDialog):
|
|
9
10
|
|
|
10
11
|
def __init__(self, process=None, parent_window=None, title="", position_info=True, process_args=None):
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
super().__init__()
|
|
14
|
+
#QDialog.__init__(self)
|
|
12
15
|
|
|
13
16
|
self.setWindowTitle(f'{title} Progress')
|
|
14
17
|
self.__process = process
|
|
15
18
|
self.parent_window = parent_window
|
|
19
|
+
|
|
16
20
|
self.position_info = position_info
|
|
17
21
|
if self.position_info:
|
|
18
22
|
self.pos_name = self.parent_window.pos_name
|