celldetective 1.2.1__py3-none-any.whl → 1.2.2__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 (51) hide show
  1. celldetective/__main__.py +12 -5
  2. celldetective/events.py +28 -2
  3. celldetective/gui/about.py +0 -1
  4. celldetective/gui/analyze_block.py +3 -18
  5. celldetective/gui/btrack_options.py +126 -21
  6. celldetective/gui/classifier_widget.py +67 -111
  7. celldetective/gui/configure_new_exp.py +37 -4
  8. celldetective/gui/control_panel.py +14 -30
  9. celldetective/gui/generic_signal_plot.py +793 -0
  10. celldetective/gui/gui_utils.py +401 -226
  11. celldetective/gui/json_readers.py +0 -2
  12. celldetective/gui/layouts.py +269 -25
  13. celldetective/gui/measurement_options.py +14 -23
  14. celldetective/gui/neighborhood_options.py +3 -15
  15. celldetective/gui/plot_measurements.py +10 -23
  16. celldetective/gui/plot_signals_ui.py +53 -687
  17. celldetective/gui/process_block.py +320 -186
  18. celldetective/gui/retrain_segmentation_model_options.py +30 -47
  19. celldetective/gui/retrain_signal_model_options.py +5 -14
  20. celldetective/gui/seg_model_loader.py +129 -113
  21. celldetective/gui/signal_annotator.py +89 -99
  22. celldetective/gui/signal_annotator2.py +5 -9
  23. celldetective/gui/styles.py +32 -0
  24. celldetective/gui/survival_ui.py +49 -712
  25. celldetective/gui/tableUI.py +0 -1
  26. celldetective/gui/thresholds_gui.py +38 -11
  27. celldetective/gui/viewers.py +6 -7
  28. celldetective/io.py +60 -82
  29. celldetective/measure.py +374 -15
  30. celldetective/neighborhood.py +1 -7
  31. celldetective/preprocessing.py +2 -4
  32. celldetective/relative_measurements.py +0 -3
  33. celldetective/scripts/analyze_signals.py +0 -1
  34. celldetective/scripts/measure_cells.py +1 -3
  35. celldetective/scripts/measure_relative.py +1 -2
  36. celldetective/scripts/segment_cells.py +16 -12
  37. celldetective/scripts/segment_cells_thresholds.py +17 -10
  38. celldetective/scripts/track_cells.py +18 -18
  39. celldetective/scripts/train_segmentation_model.py +1 -2
  40. celldetective/scripts/train_signal_model.py +0 -3
  41. celldetective/segmentation.py +1 -1
  42. celldetective/signals.py +17 -8
  43. celldetective/tracking.py +2 -1
  44. celldetective/utils.py +42 -2
  45. {celldetective-1.2.1.dist-info → celldetective-1.2.2.dist-info}/METADATA +19 -12
  46. celldetective-1.2.2.dist-info/RECORD +92 -0
  47. {celldetective-1.2.1.dist-info → celldetective-1.2.2.dist-info}/WHEEL +1 -1
  48. celldetective-1.2.1.dist-info/RECORD +0 -91
  49. {celldetective-1.2.1.dist-info → celldetective-1.2.2.dist-info}/LICENSE +0 -0
  50. {celldetective-1.2.1.dist-info → celldetective-1.2.2.dist-info}/entry_points.txt +0 -0
  51. {celldetective-1.2.1.dist-info → celldetective-1.2.2.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,6 @@
1
- import sys
2
1
  import configparser
3
2
  from PyQt5.QtWidgets import QWidget, QVBoxLayout, QScrollArea, QLabel, QHBoxLayout, QLineEdit, QPushButton
4
3
  from PyQt5.QtCore import Qt
5
- import sys
6
4
  import configparser
7
5
  from celldetective.gui import Styles
8
6
 
@@ -1,16 +1,15 @@
1
1
  from PyQt5.QtWidgets import QCheckBox, QLineEdit, QWidget, QListWidget, QTabWidget, QHBoxLayout,QMessageBox, QPushButton, QVBoxLayout, QRadioButton, QLabel, QButtonGroup, QSizePolicy, QComboBox,QSpacerItem, QGridLayout
2
- from celldetective.gui.gui_utils import ThresholdLineEdit
2
+ from celldetective.gui.gui_utils import ThresholdLineEdit, QuickSliderLayout, center_window
3
3
  from PyQt5.QtCore import Qt, QSize
4
4
  from PyQt5.QtGui import QIntValidator
5
5
 
6
- from superqt import QLabeledRangeSlider, QLabeledSlider, QLabeledDoubleRangeSlider, QSearchableComboBox
6
+ from superqt import QLabeledRangeSlider, QLabeledDoubleSlider, QLabeledSlider, QLabeledDoubleRangeSlider, QSearchableComboBox
7
7
 
8
8
  from superqt.fonticon import icon
9
9
  from fonticon_mdi6 import MDI6
10
10
  from celldetective.utils import _extract_channel_indices_from_config
11
- from celldetective.gui.viewers import ThresholdedStackVisualizer, CellEdgeVisualizer, StackVisualizer
11
+ from celldetective.gui.viewers import ThresholdedStackVisualizer, CellEdgeVisualizer, StackVisualizer, CellSizeViewer
12
12
  from celldetective.gui import Styles
13
- from celldetective.gui.gui_utils import QuickSliderLayout
14
13
  from celldetective.preprocessing import correct_background_model, correct_background_model_free, estimate_background_per_condition
15
14
  from functools import partial
16
15
  from glob import glob
@@ -18,6 +17,239 @@ import os
18
17
  import pandas as pd
19
18
  import numpy as np
20
19
 
20
+ class StarDistParamsWidget(QWidget, Styles):
21
+
22
+ """
23
+ A widget to configure parameters for StarDist segmentation.
24
+
25
+ This widget allows the user to select specific imaging channels for segmentation and adjust
26
+ parameters for StarDist, a neural network-based image segmentation tool designed to segment
27
+ star-convex shapes (typically nuclei).
28
+
29
+ Parameters
30
+ ----------
31
+ parent_window : QWidget, optional
32
+ The parent window hosting this widget (default is None).
33
+ model_name : str, optional
34
+ The name of the StarDist model being used, typically 'SD_versatile_fluo' for versatile
35
+ fluorescence or 'SD_versatile_he' for H&E-stained images (default is 'SD_versatile_fluo').
36
+ """
37
+
38
+ def __init__(self, parent_window=None, model_name='SD_versatile_fluo', *args, **kwargs):
39
+
40
+ super().__init__(*args)
41
+ self.setWindowTitle('Channels')
42
+ self.parent_window = parent_window
43
+ self.model_name = model_name
44
+
45
+ # Setting up references to parent window attributes
46
+ if hasattr(self.parent_window.parent_window, 'locate_image'):
47
+ self.attr_parent = self.parent_window.parent_window
48
+ elif hasattr(self.parent_window.parent_window.parent_window, 'locate_image'):
49
+ self.attr_parent = self.parent_window.parent_window.parent_window
50
+ else:
51
+ self.attr_parent = self.parent_window.parent_window.parent_window.parent_window
52
+
53
+ # Set up layout and widgets
54
+ self.layout = QVBoxLayout()
55
+ self.populate_widgets()
56
+ self.setLayout(self.layout)
57
+ center_window(self)
58
+
59
+ def populate_widgets(self):
60
+
61
+ """
62
+ Populates the widget with channel selection comboboxes and a 'set' button to configure
63
+ the StarDist segmentation settings. Handles different models by adjusting the number of
64
+ available channels.
65
+ """
66
+
67
+ # Initialize comboboxes based on the selected model
68
+ self.stardist_channel_cb = [QComboBox() for i in range(1)]
69
+ self.stardist_channel_template = ['live_nuclei_channel']
70
+ max_i = 1
71
+
72
+ # If the H&E model is selected, update the combobox configuration
73
+ if self.model_name=="SD_versatile_he":
74
+ self.stardist_channel_template = ["H&E_1","H&E_2","H&E_3"]
75
+ self.stardist_channel_cb = [QComboBox() for i in range(3)]
76
+ max_i = 3
77
+
78
+ # Populate the comboboxes with available channels from the experiment
79
+ for k in range(max_i):
80
+ hbox_channel = QHBoxLayout()
81
+ hbox_channel.addWidget(QLabel(f'channel {k+1}: '))
82
+ hbox_channel.addWidget(self.stardist_channel_cb[k])
83
+ if k==1:
84
+ self.stardist_channel_cb[k].addItems(list(self.attr_parent.exp_channels)+['None'])
85
+ else:
86
+ self.stardist_channel_cb[k].addItems(list(self.attr_parent.exp_channels))
87
+
88
+ # Set the default channel based on the template or fallback to the first option
89
+ idx = self.stardist_channel_cb[k].findText(self.stardist_channel_template[k])
90
+ if idx>0:
91
+ self.stardist_channel_cb[k].setCurrentIndex(idx)
92
+ else:
93
+ self.stardist_channel_cb[k].setCurrentIndex(0)
94
+
95
+ self.layout.addLayout(hbox_channel)
96
+
97
+ # Button to apply the StarDist settings
98
+ self.set_stardist_scale_btn = QPushButton('set')
99
+ self.set_stardist_scale_btn.setStyleSheet(self.button_style_sheet)
100
+ self.set_stardist_scale_btn.clicked.connect(self.parent_window.set_stardist_scale)
101
+ self.layout.addWidget(self.set_stardist_scale_btn)
102
+
103
+
104
+ class CellposeParamsWidget(QWidget, Styles):
105
+
106
+ """
107
+ A widget to configure parameters for Cellpose segmentation, allowing users to set the cell diameter,
108
+ select imaging channels, and adjust flow and cell probability thresholds for cell detection.
109
+
110
+ This widget is designed for estimating cell diameters and configuring parameters for Cellpose,
111
+ a deep learning-based segmentation tool. It also provides functionality to preview the image stack with a scale bar.
112
+
113
+ Parameters
114
+ ----------
115
+ parent_window : QWidget, optional
116
+ The parent window that hosts the widget (default is None).
117
+ model_name : str, optional
118
+ The name of the Cellpose model being used, typically 'CP_cyto2' for cytoplasm or 'CP_nuclei' for nuclei segmentation
119
+ (default is 'CP_cyto2').
120
+
121
+ Notes
122
+ -----
123
+ - This widget assumes that the parent window or one of its ancestor windows has access to the experiment channels
124
+ and can locate the current image stack via `locate_image()`.
125
+ - This class integrates sliders for flow and cell probability thresholds, as well as a channel selection for running
126
+ Cellpose segmentation.
127
+ - The `view_current_stack_with_scale_bar()` method opens a new window where the user can visually inspect the
128
+ image stack with a superimposed scale bar, to better estimate the cell diameter.
129
+
130
+ """
131
+
132
+
133
+ def __init__(self, parent_window=None, model_name='CP_cyto2', *args, **kwargs):
134
+
135
+ super().__init__(*args)
136
+ self.setWindowTitle('Estimate diameter')
137
+ self.parent_window = parent_window
138
+ self.model_name = model_name
139
+
140
+ # Setting up references to parent window attributes
141
+ if hasattr(self.parent_window.parent_window, 'locate_image'):
142
+ self.attr_parent = self.parent_window.parent_window
143
+ elif hasattr(self.parent_window.parent_window.parent_window, 'locate_image'):
144
+ self.attr_parent = self.parent_window.parent_window.parent_window
145
+ else:
146
+ self.attr_parent = self.parent_window.parent_window.parent_window.parent_window
147
+
148
+ # Layout and widgets setup
149
+ self.layout = QVBoxLayout()
150
+ self.populate_widgets()
151
+ self.setLayout(self.layout)
152
+ center_window(self)
153
+
154
+ def populate_widgets(self):
155
+
156
+ """
157
+ Populates the widget with UI elements such as buttons, sliders, and comboboxes to allow configuration
158
+ of Cellpose segmentation parameters.
159
+ """
160
+
161
+ # Button to view the current stack with a scale bar
162
+ self.view_diameter_btn = QPushButton()
163
+ self.view_diameter_btn.setStyleSheet(self.button_select_all)
164
+ self.view_diameter_btn.setIcon(icon(MDI6.image_check, color="black"))
165
+ self.view_diameter_btn.setToolTip("View stack.")
166
+ self.view_diameter_btn.setIconSize(QSize(20, 20))
167
+ self.view_diameter_btn.clicked.connect(self.view_current_stack_with_scale_bar)
168
+
169
+ # Line edit for entering cell diameter
170
+ self.diameter_le = ThresholdLineEdit(init_value=40, connected_buttons=[self.view_diameter_btn],placeholder='cell diameter in pixels', value_type='float')
171
+
172
+ # Comboboxes for selecting imaging channels
173
+ self.cellpose_channel_cb = [QComboBox() for i in range(2)]
174
+ self.cellpose_channel_template = ['brightfield_channel', 'live_nuclei_channel']
175
+ if self.model_name=="CP_nuclei":
176
+ self.cellpose_channel_template = ['live_nuclei_channel', 'None']
177
+
178
+ for k in range(2):
179
+ hbox_channel = QHBoxLayout()
180
+ hbox_channel.addWidget(QLabel(f'channel {k+1}: '))
181
+ hbox_channel.addWidget(self.cellpose_channel_cb[k])
182
+ if k==1:
183
+ self.cellpose_channel_cb[k].addItems(list(self.attr_parent.exp_channels)+['None'])
184
+ else:
185
+ self.cellpose_channel_cb[k].addItems(list(self.attr_parent.exp_channels))
186
+ idx = self.cellpose_channel_cb[k].findText(self.cellpose_channel_template[k])
187
+ if idx>0:
188
+ self.cellpose_channel_cb[k].setCurrentIndex(idx)
189
+ else:
190
+ self.cellpose_channel_cb[k].setCurrentIndex(0)
191
+
192
+ if k==1:
193
+ idx = self.cellpose_channel_cb[k].findText('None')
194
+ self.cellpose_channel_cb[k].setCurrentIndex(idx)
195
+
196
+ self.layout.addLayout(hbox_channel)
197
+
198
+ # Layout for diameter input and button
199
+ hbox = QHBoxLayout()
200
+ hbox.addWidget(QLabel('diameter [px]: '), 33)
201
+ hbox.addWidget(self.diameter_le, 61)
202
+ hbox.addWidget(self.view_diameter_btn)
203
+ self.layout.addLayout(hbox)
204
+
205
+ # Flow threshold slider
206
+ self.flow_slider = QLabeledDoubleSlider()
207
+ self.flow_slider.setOrientation(1)
208
+ self.flow_slider.setRange(-6,6)
209
+ self.flow_slider.setValue(0.4)
210
+ hbox = QHBoxLayout()
211
+ hbox.addWidget(QLabel('flow threshold: '), 33)
212
+ hbox.addWidget(self.flow_slider, 66)
213
+ self.layout.addLayout(hbox)
214
+
215
+ # Cell probability threshold slider
216
+ self.cellprob_slider = QLabeledDoubleSlider()
217
+ self.cellprob_slider.setOrientation(1)
218
+ self.cellprob_slider.setRange(-6,6)
219
+ self.cellprob_slider.setValue(0.)
220
+ hbox = QHBoxLayout()
221
+ hbox.addWidget(QLabel('cellprob threshold: '), 33)
222
+ hbox.addWidget(self.cellprob_slider, 66)
223
+ self.layout.addLayout(hbox)
224
+
225
+ # Button to set the scale for Cellpose segmentation
226
+ self.set_cellpose_scale_btn = QPushButton('set')
227
+ self.set_cellpose_scale_btn.setStyleSheet(self.button_style_sheet)
228
+ self.set_cellpose_scale_btn.clicked.connect(self.parent_window.set_cellpose_scale)
229
+ self.layout.addWidget(self.set_cellpose_scale_btn)
230
+
231
+ def view_current_stack_with_scale_bar(self):
232
+
233
+ """
234
+ Displays the current image stack with a scale bar, allowing users to visually estimate cell diameters.
235
+ """
236
+
237
+ self.attr_parent.locate_image()
238
+ if self.attr_parent.current_stack is not None:
239
+ self.viewer = CellSizeViewer(
240
+ initial_diameter = float(self.diameter_le.text().replace(',', '.')),
241
+ parent_le = self.diameter_le,
242
+ stack_path=self.attr_parent.current_stack,
243
+ window_title=f'Position {self.attr_parent.position_list.currentText()}',
244
+ frame_slider = True,
245
+ contrast_slider = True,
246
+ channel_cb = True,
247
+ channel_names = self.attr_parent.exp_channels,
248
+ n_channels = self.attr_parent.nbr_channels,
249
+ PxToUm = 1,
250
+ )
251
+ self.viewer.show()
252
+
21
253
  class ChannelNormGenerator(QVBoxLayout, Styles):
22
254
 
23
255
  """Generator for list of channels"""
@@ -44,6 +276,8 @@ class ChannelNormGenerator(QVBoxLayout, Styles):
44
276
  def generate_widgets(self):
45
277
 
46
278
  self.channel_cbs = [QSearchableComboBox() for i in range(self.init_n_channels)]
279
+ self.channel_labels = [QLabel() for i in range(self.init_n_channels)]
280
+
47
281
  self.normalization_mode_btns = [QPushButton('') for i in range(self.init_n_channels)]
48
282
  self.normalization_mode = [True for i in range(self.init_n_channels)]
49
283
  self.normalization_clip_btns = [QPushButton('') for i in range(self.init_n_channels)]
@@ -127,8 +361,10 @@ class ChannelNormGenerator(QVBoxLayout, Styles):
127
361
  def add_channel(self):
128
362
 
129
363
  self.channel_cbs.append(QSearchableComboBox())
364
+ self.channel_labels.append(QLabel())
130
365
  self.channel_cbs[-1].addItems(self.channel_items)
131
366
  self.channel_cbs[-1].currentIndexChanged.connect(self.check_valid_channels)
367
+ self.channel_labels[-1].setText(f'channel {len(self.channel_cbs)-1}: ')
132
368
 
133
369
  self.normalization_mode_btns.append(QPushButton(''))
134
370
  self.normalization_mode.append(True)
@@ -153,18 +389,21 @@ class ChannelNormGenerator(QVBoxLayout, Styles):
153
389
  self.normalization_max_value_le.append(QLineEdit('99.99'))
154
390
 
155
391
  ch_layout = QHBoxLayout()
156
- ch_layout.addWidget(QLabel(f'channel {len(self.channel_cbs)-1}: '), 30)
392
+ ch_layout.addWidget(self.channel_labels[-1], 30)
157
393
  ch_layout.addWidget(self.channel_cbs[-1], 70)
158
394
  self.channels_vb.addLayout(ch_layout)
159
395
 
160
396
  channel_norm_options_layout = QHBoxLayout()
161
- channel_norm_options_layout.setContentsMargins(130,0,0,0)
162
- channel_norm_options_layout.addWidget(self.normalization_min_value_lbl[-1])
163
- channel_norm_options_layout.addWidget(self.normalization_min_value_le[-1])
164
- channel_norm_options_layout.addWidget(self.normalization_max_value_lbl[-1])
165
- channel_norm_options_layout.addWidget(self.normalization_max_value_le[-1])
166
- channel_norm_options_layout.addWidget(self.normalization_clip_btns[-1])
167
- channel_norm_options_layout.addWidget(self.normalization_mode_btns[-1])
397
+ channel_norm_options_layout.addWidget(QLabel(''),30)
398
+ ch_norm_sublayout = QHBoxLayout()
399
+ ch_norm_sublayout.addWidget(self.normalization_min_value_lbl[-1])
400
+ ch_norm_sublayout.addWidget(self.normalization_min_value_le[-1])
401
+ ch_norm_sublayout.addWidget(self.normalization_max_value_lbl[-1])
402
+ ch_norm_sublayout.addWidget(self.normalization_max_value_le[-1])
403
+ ch_norm_sublayout.addWidget(self.normalization_clip_btns[-1])
404
+ ch_norm_sublayout.addWidget(self.normalization_mode_btns[-1])
405
+ channel_norm_options_layout.addLayout(ch_norm_sublayout, 70)
406
+
168
407
  self.channels_vb.addLayout(channel_norm_options_layout)
169
408
 
170
409
 
@@ -175,20 +414,24 @@ class ChannelNormGenerator(QVBoxLayout, Styles):
175
414
  for i in range(len(self.channel_cbs)):
176
415
 
177
416
  ch_layout = QHBoxLayout()
178
- ch_layout.addWidget(QLabel(f'channel {i}: '), 30)
417
+ self.channel_labels[i].setText(f'channel {i}: ')
418
+ ch_layout.addWidget(self.channel_labels[i], 30)
179
419
  self.channel_cbs[i].addItems(self.channel_items)
180
420
  self.channel_cbs[i].currentIndexChanged.connect(self.check_valid_channels)
181
421
  ch_layout.addWidget(self.channel_cbs[i], 70)
182
422
  self.channels_vb.addLayout(ch_layout)
183
423
 
184
424
  channel_norm_options_layout = QHBoxLayout()
185
- channel_norm_options_layout.setContentsMargins(130,0,0,0)
186
- channel_norm_options_layout.addWidget(self.normalization_min_value_lbl[i])
187
- channel_norm_options_layout.addWidget(self.normalization_min_value_le[i])
188
- channel_norm_options_layout.addWidget(self.normalization_max_value_lbl[i])
189
- channel_norm_options_layout.addWidget(self.normalization_max_value_le[i])
190
- channel_norm_options_layout.addWidget(self.normalization_clip_btns[i])
191
- channel_norm_options_layout.addWidget(self.normalization_mode_btns[i])
425
+ #channel_norm_options_layout.setContentsMargins(130,0,0,0)
426
+ channel_norm_options_layout.addWidget(QLabel(''),30)
427
+ ch_norm_sublayout = QHBoxLayout()
428
+ ch_norm_sublayout.addWidget(self.normalization_min_value_lbl[i])
429
+ ch_norm_sublayout.addWidget(self.normalization_min_value_le[i])
430
+ ch_norm_sublayout.addWidget(self.normalization_max_value_lbl[i])
431
+ ch_norm_sublayout.addWidget(self.normalization_max_value_le[i])
432
+ ch_norm_sublayout.addWidget(self.normalization_clip_btns[i])
433
+ ch_norm_sublayout.addWidget(self.normalization_mode_btns[i])
434
+ channel_norm_options_layout.addLayout(ch_norm_sublayout, 70)
192
435
  self.channels_vb.addLayout(channel_norm_options_layout)
193
436
 
194
437
  self.addLayout(self.channels_vb)
@@ -249,7 +492,7 @@ class ChannelNormGenerator(QVBoxLayout, Styles):
249
492
  if np.all([cb.currentText()=='--' for cb in self.channel_cbs]):
250
493
  self.parent_window.submit_btn.setEnabled(False)
251
494
 
252
- if hasattr(self.parent_window, "spatial_calib_le"):
495
+ if hasattr(self.parent_window, "spatial_calib_le") and hasattr(self.parent_window, "submit_btn"):
253
496
  if self.parent_window.spatial_calib_le.text()!='--':
254
497
  self.parent_window.submit_btn.setEnabled(True)
255
498
  elif hasattr(self.parent_window, "submit_btn"):
@@ -619,7 +862,6 @@ class ProtocolDesignerLayout(QVBoxLayout, Styles):
619
862
 
620
863
  for k in range(len(self.tab_layouts)):
621
864
  wg = QWidget()
622
- print('almost there',self.channel_names)
623
865
  self.tab_layouts[k].parent_window = self
624
866
  wg.setLayout(self.tab_layouts[k])
625
867
  self.tabs.addTab(wg, self.tab_names[k])
@@ -635,8 +877,11 @@ class ProtocolDesignerLayout(QVBoxLayout, Styles):
635
877
  self.delete_protocol_btn.clicked.connect(self.remove_protocol_from_list)
636
878
 
637
879
  def generate_layout(self):
638
-
639
- self.addWidget(self.title_lbl, alignment=Qt.AlignCenter)
880
+
881
+ self.title_layout = QHBoxLayout()
882
+ self.title_layout.addWidget(self.title_lbl, 100, alignment=Qt.AlignCenter)
883
+
884
+ self.addLayout(self.title_layout)
640
885
  self.addWidget(self.tabs)
641
886
 
642
887
  list_header_layout = QHBoxLayout()
@@ -692,7 +937,6 @@ class BackgroundModelFreeCorrectionLayout(QGridLayout, Styles):
692
937
  from PyQt5.QtWidgets import QSlider
693
938
  from superqt import QRangeSlider
694
939
  self.frame_range_slider = QLabeledRangeSlider(parent=None)
695
- print('here ok')
696
940
 
697
941
  self.timeseries_rb.toggled.connect(self.activate_time_range)
698
942
  self.tiles_rb.toggled.connect(self.activate_time_range)
@@ -1,43 +1,33 @@
1
- import math
2
1
 
3
- import skimage
4
2
  from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QScrollArea, QComboBox, QFrame, QCheckBox, \
5
- QFileDialog, QGridLayout, QTextEdit, QLineEdit, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton, QTabWidget, \
6
- QRadioButton, QButtonGroup, QSizePolicy, QListWidget, QDialog
3
+ QGridLayout, QLineEdit, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton
7
4
  from PyQt5.QtCore import Qt, QSize
8
5
  from PyQt5.QtGui import QIcon, QDoubleValidator, QIntValidator
9
- from matplotlib.patches import Circle
10
- from scipy import ndimage
11
- from skimage.draw import disk
12
- from skimage.morphology import disk
13
6
 
14
- from celldetective.filters import std_filter, gauss_filter
15
7
  from celldetective.gui.gui_utils import center_window, FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, \
16
- GeometryChoice, OperationChoice, ChannelChoice
17
- from superqt import QLabeledDoubleRangeSlider, QLabeledDoubleSlider, QLabeledSlider
8
+ GeometryChoice, OperationChoice
9
+ from superqt import QLabeledDoubleSlider
18
10
  from superqt.fonticon import icon
19
11
  from fonticon_mdi6 import MDI6
20
12
 
21
- from celldetective.gui.thresholds_gui import ThresholdNormalisation, ThresholdSpot
13
+ from celldetective.gui.thresholds_gui import ThresholdSpot
22
14
  from celldetective.utils import extract_experiment_channels, get_software_location
23
- from celldetective.io import interpret_tracking_configuration, load_frames, auto_load_number_of_frames
24
- from celldetective.measure import compute_haralick_features, contour_of_instance_segmentation, normalise_by_cell
15
+ from celldetective.io import load_frames, auto_load_number_of_frames
16
+ from celldetective.measure import compute_haralick_features
25
17
  import numpy as np
26
18
  from tifffile import imread
27
19
  import json
28
- from shutil import copyfile
29
20
  import os
30
21
  import matplotlib.pyplot as plt
31
22
  from mpl_toolkits.axes_grid1 import make_axes_locatable
32
23
  from glob import glob
33
24
  from natsort import natsorted
34
25
  from tifffile import imread
35
- from pathlib import Path, PurePath
26
+ from pathlib import Path
36
27
  import gc
37
- from stardist import fill_label_holes
38
28
 
39
29
  from celldetective.gui.viewers import CellEdgeVisualizer
40
- from celldetective.gui.layouts import ProtocolDesignerLayout, BackgroundFitCorrectionLayout, LocalCorrectionLayout, OperationLayout
30
+ from celldetective.gui.layouts import ProtocolDesignerLayout, BackgroundFitCorrectionLayout, LocalCorrectionLayout
41
31
  from celldetective.gui.gui_utils import ThresholdLineEdit
42
32
  from celldetective.gui import Styles
43
33
 
@@ -217,7 +207,7 @@ class ConfigMeasurements(QMainWindow, Styles):
217
207
  radii_layout.addWidget(self.add_radius_btn, 5)
218
208
  layout.addLayout(radii_layout)
219
209
 
220
- self.radii_list = ListWidget(self, GeometryChoice, initial_features=["10"], dtype=int)
210
+ self.radii_list = ListWidget(GeometryChoice, initial_features=["10"], dtype=int)
221
211
  layout.addWidget(self.radii_list)
222
212
 
223
213
  self.del_radius_btn.clicked.connect(self.radii_list.removeSel)
@@ -244,7 +234,7 @@ class ConfigMeasurements(QMainWindow, Styles):
244
234
  operation_layout.addWidget(self.add_op_btn, 5)
245
235
  layout.addLayout(operation_layout)
246
236
 
247
- self.operations_list = ListWidget(self, OperationChoice, initial_features=["mean"])
237
+ self.operations_list = ListWidget(OperationChoice, initial_features=["mean"])
248
238
  layout.addWidget(self.operations_list)
249
239
 
250
240
  self.del_op_btn.clicked.connect(self.operations_list.removeSel)
@@ -272,7 +262,7 @@ class ConfigMeasurements(QMainWindow, Styles):
272
262
  self.add_feature_btn.setToolTip("Add feature")
273
263
  self.add_feature_btn.setIconSize(QSize(20, 20))
274
264
 
275
- self.features_list = ListWidget(self, FeatureChoice, initial_features=['area', 'intensity_mean', ])
265
+ self.features_list = ListWidget(FeatureChoice, initial_features=['area', 'intensity_mean', ])
276
266
 
277
267
  self.del_feature_btn.clicked.connect(self.features_list.removeSel)
278
268
  self.add_feature_btn.clicked.connect(self.features_list.addItem)
@@ -315,7 +305,7 @@ class ConfigMeasurements(QMainWindow, Styles):
315
305
 
316
306
  layout.addLayout(contour_layout)
317
307
 
318
- self.contours_list = ListWidget(self, GeometryChoice, initial_features=[], dtype=int)
308
+ self.contours_list = ListWidget(GeometryChoice, initial_features=[], dtype=int)
319
309
  layout.addWidget(self.contours_list)
320
310
 
321
311
  self.del_contour_btn.clicked.connect(self.contours_list.removeSel)
@@ -797,7 +787,8 @@ class ConfigMeasurements(QMainWindow, Styles):
797
787
  self.fig, self.ax = plt.subplots(1, 1, figsize=(4, 3))
798
788
  self.hist_window = FigureCanvas(self.fig, title="Haralick: control digitized histogram")
799
789
  self.ax.clear()
800
- self.ax.hist(norm_img.flatten(), bins=self.haralick_options['n_intensity_bins'])
790
+ flat = norm_img.flatten()
791
+ self.ax.hist(flat[flat==flat], bins=self.haralick_options['n_intensity_bins'])
801
792
  self.ax.set_xlabel('gray level value')
802
793
  self.ax.set_ylabel('#')
803
794
  plt.tight_layout()
@@ -1,25 +1,13 @@
1
- from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QScrollArea, QComboBox, QFrame, QCheckBox, QFileDialog, QGridLayout, QTextEdit, QLineEdit, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton
1
+ from PyQt5.QtWidgets import QApplication, QComboBox, QFrame, QCheckBox, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton
2
2
  from PyQt5.QtCore import Qt, QSize
3
3
  from PyQt5.QtGui import QIcon
4
- from celldetective.gui.gui_utils import center_window, FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, DistanceChoice, OperationChoice
5
- from superqt import QLabeledDoubleRangeSlider, QLabeledDoubleSlider,QLabeledSlider
4
+ from celldetective.gui.gui_utils import center_window, ListWidget, DistanceChoice
6
5
  from superqt.fonticon import icon
7
6
  from fonticon_mdi6 import MDI6
8
- from celldetective.utils import extract_experiment_channels, get_software_location
9
- from celldetective.io import interpret_tracking_configuration, load_frames, auto_load_number_of_frames
10
- from celldetective.measure import compute_haralick_features, contour_of_instance_segmentation
11
7
  import numpy as np
12
- from tifffile import imread
13
8
  import json
14
- from shutil import copyfile
15
9
  import os
16
- import matplotlib.pyplot as plt
17
- from mpl_toolkits.axes_grid1 import make_axes_locatable
18
10
  from glob import glob
19
- from natsort import natsorted
20
- from tifffile import imread
21
- from pathlib import Path, PurePath
22
- import gc
23
11
  import pandas as pd
24
12
  from celldetective.gui.viewers import CellSizeViewer, CellEdgeVisualizer
25
13
  from celldetective.gui import Styles
@@ -152,7 +140,7 @@ class ConfigNeighborhoods(QWidget, Styles):
152
140
 
153
141
  layout.addLayout(list_header_layout)
154
142
 
155
- self.measurements_list = ListWidget(self, DistanceChoice, initial_features=["60"], dtype=int)
143
+ self.measurements_list = ListWidget(DistanceChoice, initial_features=["60"], dtype=int)
156
144
  self.measurements_list.setToolTip('Neighborhoods to compute.')
157
145
  layout.addWidget(self.measurements_list)
158
146
 
@@ -1,40 +1,27 @@
1
- from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QScrollArea, QButtonGroup, QComboBox, QFrame, \
2
- QCheckBox, QFileDialog, QGridLayout, QTextEdit, QLineEdit, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton, \
3
- QRadioButton, QSpacerItem, QSizePolicy
4
- from PyQt5.QtCore import Qt, QSize, QRect
1
+ from PyQt5.QtWidgets import QMessageBox, QScrollArea, QButtonGroup, QComboBox, \
2
+ QCheckBox, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton, \
3
+ QRadioButton, QSizePolicy
4
+ from PyQt5.QtCore import Qt, QRect
5
5
  from PyQt5.QtGui import QIcon, QDoubleValidator
6
- from sklearn.preprocessing import MinMaxScaler
7
6
 
8
7
  from celldetective.gui import Styles
9
- from celldetective.gui.gui_utils import center_window, FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, \
10
- GeometryChoice, OperationChoice
11
- from superqt import QLabeledSlider
8
+ from celldetective.gui.gui_utils import center_window, FigureCanvas
9
+
12
10
  from superqt.fonticon import icon
13
11
  from fonticon_mdi6 import MDI6
14
- from celldetective.utils import extract_experiment_channels, get_software_location, _extract_labels_from_config
15
- from celldetective.io import interpret_tracking_configuration, load_frames, auto_load_number_of_frames, \
16
- load_experiment_tables, get_experiment_antibodies, get_experiment_cell_types, get_experiment_concentrations, \
12
+ from celldetective.utils import get_software_location, _extract_labels_from_config
13
+ from celldetective.io import load_experiment_tables, get_experiment_antibodies, get_experiment_cell_types, get_experiment_concentrations, \
17
14
  get_positions_in_well, get_experiment_wells
18
- from celldetective.measure import compute_haralick_features, contour_of_instance_segmentation
19
- from celldetective.signals import columnwise_mean, mean_signal
15
+ from celldetective.signals import mean_signal
20
16
  import numpy as np
21
- from tifffile import imread
22
17
  import json
23
- from shutil import copyfile
24
18
  import os
25
19
  import matplotlib.pyplot as plt
26
20
 
27
21
  plt.rcParams['svg.fonttype'] = 'none'
28
- from mpl_toolkits.axes_grid1 import make_axes_locatable
29
22
  from glob import glob
30
- from natsort import natsorted
31
- from tifffile import imread
32
- from pathlib import Path, PurePath
33
- import gc
34
23
  import pandas as pd
35
- from tqdm import tqdm
36
- from lifelines import KaplanMeierFitter
37
- from matplotlib.cm import viridis, tab10
24
+ from matplotlib.cm import tab10
38
25
  import math
39
26
  import seaborn as sns
40
27