celldetective 1.3.9.post4__py3-none-any.whl → 1.4.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.
Files changed (57) hide show
  1. celldetective/__init__.py +0 -3
  2. celldetective/_version.py +1 -1
  3. celldetective/events.py +2 -4
  4. celldetective/extra_properties.py +320 -24
  5. celldetective/gui/InitWindow.py +33 -45
  6. celldetective/gui/__init__.py +1 -0
  7. celldetective/gui/about.py +19 -15
  8. celldetective/gui/analyze_block.py +34 -19
  9. celldetective/gui/base_components.py +23 -0
  10. celldetective/gui/btrack_options.py +26 -34
  11. celldetective/gui/classifier_widget.py +71 -80
  12. celldetective/gui/configure_new_exp.py +113 -17
  13. celldetective/gui/control_panel.py +68 -141
  14. celldetective/gui/generic_signal_plot.py +9 -12
  15. celldetective/gui/gui_utils.py +49 -21
  16. celldetective/gui/json_readers.py +5 -4
  17. celldetective/gui/layouts.py +246 -22
  18. celldetective/gui/measurement_options.py +32 -17
  19. celldetective/gui/neighborhood_options.py +10 -13
  20. celldetective/gui/plot_measurements.py +21 -17
  21. celldetective/gui/plot_signals_ui.py +131 -75
  22. celldetective/gui/process_block.py +180 -123
  23. celldetective/gui/processes/compute_neighborhood.py +594 -0
  24. celldetective/gui/processes/measure_cells.py +5 -0
  25. celldetective/gui/processes/segment_cells.py +27 -6
  26. celldetective/gui/processes/track_cells.py +6 -0
  27. celldetective/gui/retrain_segmentation_model_options.py +12 -20
  28. celldetective/gui/retrain_signal_model_options.py +57 -56
  29. celldetective/gui/seg_model_loader.py +21 -62
  30. celldetective/gui/signal_annotator.py +139 -72
  31. celldetective/gui/signal_annotator2.py +431 -635
  32. celldetective/gui/signal_annotator_options.py +8 -11
  33. celldetective/gui/survival_ui.py +49 -95
  34. celldetective/gui/tableUI.py +28 -25
  35. celldetective/gui/thresholds_gui.py +617 -1221
  36. celldetective/gui/viewers.py +106 -39
  37. celldetective/gui/workers.py +9 -3
  38. celldetective/io.py +73 -27
  39. celldetective/measure.py +63 -27
  40. celldetective/neighborhood.py +342 -268
  41. celldetective/preprocessing.py +25 -17
  42. celldetective/relative_measurements.py +50 -29
  43. celldetective/scripts/analyze_signals.py +4 -1
  44. celldetective/scripts/measure_relative.py +4 -1
  45. celldetective/scripts/segment_cells.py +0 -6
  46. celldetective/scripts/track_cells.py +3 -1
  47. celldetective/scripts/train_segmentation_model.py +7 -4
  48. celldetective/signals.py +29 -14
  49. celldetective/tracking.py +7 -2
  50. celldetective/utils.py +36 -8
  51. {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/METADATA +24 -16
  52. {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/RECORD +57 -55
  53. {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/WHEEL +1 -1
  54. tests/test_qt.py +21 -21
  55. {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/entry_points.txt +0 -0
  56. {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info/licenses}/LICENSE +0 -0
  57. {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,14 @@
1
1
  from PyQt5.QtWidgets import QFrame, QLabel, QPushButton, QVBoxLayout, \
2
- QSpacerItem, QSizePolicy
2
+ QSpacerItem, QSizePolicy
3
3
  from PyQt5.QtCore import Qt, QSize
4
4
  from PyQt5.QtGui import QIcon
5
- from celldetective.gui.plot_measurements import ConfigMeasurementsPlot
6
5
  from celldetective.gui import ConfigSurvival, ConfigSignalPlot
7
6
  import os
8
7
  from celldetective.gui import Styles
8
+ from glob import glob
9
+
10
+ from celldetective.gui.gui_utils import generic_message
11
+
9
12
 
10
13
  class AnalysisPanel(QFrame, Styles):
11
14
  def __init__(self, parent_window, title=None):
@@ -14,10 +17,11 @@ class AnalysisPanel(QFrame, Styles):
14
17
  self.parent_window = parent_window
15
18
  self.title = title
16
19
  if self.title is None:
17
- self.title=''
20
+ self.title = ''
18
21
  self.exp_channels = self.parent_window.exp_channels
19
22
  self.exp_dir = self.parent_window.exp_dir
20
23
  self.soft_path = self.parent_window.parent_window.soft_path
24
+ self.pop_exists = False
21
25
 
22
26
  self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
23
27
  self.grid = QVBoxLayout(self)
@@ -40,7 +44,7 @@ class AnalysisPanel(QFrame, Styles):
40
44
  self.grid.addWidget(panel_title, alignment=Qt.AlignCenter)
41
45
 
42
46
  self.survival_btn = QPushButton("plot survival")
43
- self.survival_btn.setIcon(QIcon(QIcon(os.sep.join([self.soft_path,'celldetective','icons','survival2.png']))))
47
+ self.survival_btn.setIcon(QIcon(QIcon(os.sep.join([self.soft_path, 'celldetective', 'icons', 'survival2.png']))))
44
48
  self.survival_btn.setStyleSheet(self.button_style_sheet_2)
45
49
  self.survival_btn.setIconSize(QSize(35, 35))
46
50
  self.survival_btn.clicked.connect(self.configure_survival)
@@ -55,27 +59,38 @@ class AnalysisPanel(QFrame, Styles):
55
59
  self.grid.addWidget(signal_lbl, alignment=Qt.AlignCenter)
56
60
 
57
61
  self.plot_signal_btn = QPushButton("plot signals")
58
- self.plot_signal_btn.setIcon(QIcon(QIcon(os.sep.join([self.soft_path,'celldetective','icons','signals_icon.png']))))
62
+ self.plot_signal_btn.setIcon(QIcon(QIcon(os.sep.join([self.soft_path, 'celldetective', 'icons', 'signals_icon.png']))))
59
63
  self.plot_signal_btn.setStyleSheet(self.button_style_sheet_2)
60
64
  self.plot_signal_btn.setIconSize(QSize(35, 35))
61
65
  self.plot_signal_btn.clicked.connect(self.configure_plot_signals)
62
66
  self.grid.addWidget(self.plot_signal_btn)
63
67
 
64
- verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
65
- self.grid.addItem(verticalSpacer)
68
+ vertical_spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
69
+ self.grid.addItem(vertical_spacer)
66
70
 
71
+ def check_for_tables(self):
72
+
73
+ for population in self.parent_window.populations:
74
+ tables = glob(self.exp_dir + os.sep.join(['W*', '*', 'output', 'tables', f'trajectories_{population}.csv']))
75
+ if len(tables) > 0:
76
+ self.pop_exists = True
77
+
67
78
  def configure_survival(self):
68
- print('survival analysis starting!!!')
69
- self.configSurvival = ConfigSurvival(self)
70
- self.configSurvival.show()
79
+
80
+ self.check_for_tables()
81
+ if self.pop_exists:
82
+ self.configSurvival = ConfigSurvival(self)
83
+ self.configSurvival.show()
84
+ else:
85
+ generic_message("No population table could be found... Abort...")
86
+ return None
71
87
 
72
88
  def configure_plot_signals(self):
73
- print('Configure a signal collapse representation...')
74
- self.ConfigSignalPlot = ConfigSignalPlot(self)
75
- self.ConfigSignalPlot.show()
76
-
77
- def configure_plot_measurements(self):
78
-
79
- print('plot measurements analysis starting!!!')
80
- self.ConfigMeasurementsPlot_wg = ConfigMeasurementsPlot(self)
81
- self.ConfigMeasurementsPlot_wg.show()
89
+
90
+ self.check_for_tables()
91
+ if self.pop_exists:
92
+ self.ConfigSignalPlot = ConfigSignalPlot(self)
93
+ self.ConfigSignalPlot.show()
94
+ else:
95
+ generic_message("No population table could be found... Abort...")
96
+ return None
@@ -0,0 +1,23 @@
1
+ from PyQt5.QtWidgets import QMainWindow, QWidget, QDialog
2
+ from PyQt5.QtCore import Qt
3
+ from celldetective.gui import Styles
4
+
5
+
6
+ class CelldetectiveWidget(QWidget, Styles):
7
+ def __init__(self, *args, **kwargs):
8
+ super().__init__(*args, **kwargs)
9
+ self.setWindowIcon(self.celldetective_icon)
10
+ self.setAttribute(Qt.WA_DeleteOnClose)
11
+
12
+
13
+ class CelldetectiveMainWindow(QMainWindow, Styles):
14
+ def __init__(self, *args, **kwargs):
15
+ super().__init__(*args, **kwargs)
16
+ self.setWindowIcon(self.celldetective_icon)
17
+ self.setAttribute(Qt.WA_DeleteOnClose)
18
+
19
+
20
+ class CelldetectiveDialog(QDialog, Styles):
21
+ def __init__(self, *args, **kwargs):
22
+ super().__init__(*args, **kwargs)
23
+ self.setWindowIcon(self.celldetective_icon)
@@ -1,9 +1,9 @@
1
- from PyQt5.QtWidgets import QRadioButton, QButtonGroup, QMainWindow, QApplication, QMessageBox, QScrollArea, QComboBox, QFrame, QCheckBox, QFileDialog, QGridLayout, QTextEdit, QLineEdit, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton
1
+ from PyQt5.QtWidgets import QRadioButton, QButtonGroup, QApplication, QMessageBox, QScrollArea, QComboBox, QFrame, QCheckBox, QFileDialog, QGridLayout, QTextEdit, QLineEdit, QVBoxLayout, QLabel, QHBoxLayout, QPushButton
2
2
  from PyQt5.QtCore import Qt, QSize
3
3
  from PyQt5.QtGui import QDoubleValidator
4
4
 
5
5
  from celldetective.gui.gui_utils import center_window, FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, help_generic
6
- from superqt import QLabeledDoubleSlider,QLabeledSlider
6
+ from superqt import QLabeledDoubleSlider, QLabeledSlider
7
7
  from superqt.fonticon import icon
8
8
  from fonticon_mdi6 import MDI6
9
9
  from celldetective.utils import extract_experiment_channels, get_software_location
@@ -16,9 +16,10 @@ import os
16
16
  import matplotlib.pyplot as plt
17
17
  from mpl_toolkits.axes_grid1 import make_axes_locatable
18
18
  from glob import glob
19
- from celldetective.gui import Styles
19
+ from celldetective.gui import CelldetectiveWidget, CelldetectiveMainWindow
20
20
 
21
- class ConfigTracking(QMainWindow, Styles):
21
+
22
+ class ConfigTracking(CelldetectiveMainWindow):
22
23
 
23
24
  """
24
25
  UI to set tracking parameters for bTrack.
@@ -34,15 +35,10 @@ class ConfigTracking(QMainWindow, Styles):
34
35
  self.exp_dir = self.parent_window.exp_dir
35
36
  self.floatValidator = QDoubleValidator()
36
37
 
37
- if self.mode=="targets":
38
- self.config_name = os.sep.join(["configs", "btrack_config_targets.json"])
39
- self.track_instructions_write_path = self.parent_window.exp_dir + os.sep.join(["configs","tracking_instructions_targets.json"])
40
- elif self.mode=="effectors":
41
- self.config_name = os.sep.join(["configs","btrack_config_effectors.json"])
42
- self.track_instructions_write_path = self.parent_window.exp_dir + os.sep.join(["configs", "tracking_instructions_effectors.json"])
38
+ self.config_name = os.sep.join(["configs", f"btrack_config_{self.mode}.json"])
39
+ self.track_instructions_write_path = self.parent_window.exp_dir + os.sep.join(["configs", f"tracking_instructions_{self.mode}.json"])
43
40
  self.soft_path = get_software_location()
44
41
 
45
- exp_config = self.exp_dir +"config.ini"
46
42
  self.config_path = self.exp_dir + self.config_name
47
43
  self.channel_names, self.channels = extract_experiment_channels(self.exp_dir)
48
44
  self.channel_names = np.array(self.channel_names)
@@ -66,10 +62,10 @@ class ConfigTracking(QMainWindow, Styles):
66
62
 
67
63
  # Create button widget and layout
68
64
  self.scroll_area = QScrollArea(self)
69
- self.button_widget = QWidget()
65
+ self.button_widget = CelldetectiveWidget()
70
66
  main_layout = QVBoxLayout()
71
67
  self.button_widget.setLayout(main_layout)
72
- main_layout.setContentsMargins(30,30,30,30)
68
+ main_layout.setContentsMargins(30, 30, 30, 30)
73
69
 
74
70
  # First collapsable Frame CONFIG
75
71
 
@@ -86,7 +82,7 @@ class ConfigTracking(QMainWindow, Styles):
86
82
  self.populate_config_frame()
87
83
 
88
84
  tracker_hbox = QHBoxLayout()
89
- tracker_hbox.setContentsMargins(15,15,15,15)
85
+ tracker_hbox.setContentsMargins(15, 15, 15, 15)
90
86
  tracker_hbox.addWidget(self.btrack_option, 50, alignment=Qt.AlignCenter)
91
87
  tracker_hbox.addWidget(self.trackpy_option, 50, alignment=Qt.AlignCenter)
92
88
  main_layout.addLayout(tracker_hbox)
@@ -149,7 +145,6 @@ class ConfigTracking(QMainWindow, Styles):
149
145
  #self.scroll_area.setMinimumHeight(self.minimum_height)
150
146
  #self.adjustSize()
151
147
 
152
-
153
148
  def populate_post_proc_frame(self):
154
149
 
155
150
  """
@@ -172,13 +167,13 @@ class ConfigTracking(QMainWindow, Styles):
172
167
  title_hbox = QHBoxLayout()
173
168
 
174
169
  self.collapse_post_proc_btn = QPushButton()
175
- self.collapse_post_proc_btn.setIcon(icon(MDI6.chevron_down,color="black"))
170
+ self.collapse_post_proc_btn.setIcon(icon(MDI6.chevron_down, color="black"))
176
171
  self.collapse_post_proc_btn.setIconSize(QSize(20, 20))
177
172
  self.collapse_post_proc_btn.setStyleSheet(self.button_select_all)
178
173
  #grid.addWidget(self.collapse_post_proc_btn, 0, 0, 1, 4, alignment=Qt.AlignRight)
179
174
 
180
175
  self.help_post_btn = QPushButton()
181
- self.help_post_btn.setIcon(icon(MDI6.help_circle,color=self.help_color))
176
+ self.help_post_btn.setIcon(icon(MDI6.help_circle, color=self.help_color))
182
177
  self.help_post_btn.setIconSize(QSize(20, 20))
183
178
  self.help_post_btn.clicked.connect(self.help_post)
184
179
  self.help_post_btn.setStyleSheet(self.button_select_all)
@@ -188,7 +183,7 @@ class ConfigTracking(QMainWindow, Styles):
188
183
  title_hbox.addWidget(QLabel(), 85, alignment=Qt.AlignCenter)
189
184
  title_hbox.addWidget(self.help_post_btn, 5)
190
185
  title_hbox.addWidget(self.collapse_post_proc_btn, 5)
191
- grid.addLayout(title_hbox, 0,0,1,4)
186
+ grid.addLayout(title_hbox, 0, 0, 1, 4)
192
187
 
193
188
  self.generate_post_proc_panel_contents()
194
189
  grid.addWidget(self.ContentsPostProc, 1, 0, 1, 4, alignment=Qt.AlignTop)
@@ -205,13 +200,13 @@ class ConfigTracking(QMainWindow, Styles):
205
200
  is_open = np.array([features_open, config_open, post_open])
206
201
 
207
202
  if self.ContentsPostProc.isHidden():
208
- self.collapse_post_proc_btn.setIcon(icon(MDI6.chevron_down,color="black"))
203
+ self.collapse_post_proc_btn.setIcon(icon(MDI6.chevron_down, color="black"))
209
204
  self.collapse_post_proc_btn.setIconSize(QSize(20, 20))
210
205
  if len(is_open[is_open])==0:
211
206
  self.scroll_area.setMinimumHeight(int(self.minimum_height))
212
207
  self.adjustSize()
213
208
  else:
214
- self.collapse_post_proc_btn.setIcon(icon(MDI6.chevron_up,color="black"))
209
+ self.collapse_post_proc_btn.setIcon(icon(MDI6.chevron_up, color="black"))
215
210
  self.collapse_post_proc_btn.setIconSize(QSize(20, 20))
216
211
  self.scroll_area.setMinimumHeight(min(int(930), int(0.9*self.screen_height)))
217
212
 
@@ -222,7 +217,7 @@ class ConfigTracking(QMainWindow, Styles):
222
217
  Helper for track post-processing strategy.
223
218
  """
224
219
 
225
- dict_path = os.sep.join([get_software_location(),'celldetective','gui','help','track-postprocessing.json'])
220
+ dict_path = os.sep.join([get_software_location(), 'celldetective', 'gui', 'help', 'track-postprocessing.json'])
226
221
 
227
222
  with open(dict_path) as f:
228
223
  d = json.load(f)
@@ -246,7 +241,7 @@ class ConfigTracking(QMainWindow, Styles):
246
241
  Helper for track post-processing strategy.
247
242
  """
248
243
 
249
- dict_path = os.sep.join([get_software_location(),'celldetective','gui','help','feature-btrack.json'])
244
+ dict_path = os.sep.join([get_software_location(), 'celldetective', 'gui', 'help', 'feature-btrack.json'])
250
245
 
251
246
  with open(dict_path) as f:
252
247
  d = json.load(f)
@@ -300,7 +295,7 @@ class ConfigTracking(QMainWindow, Styles):
300
295
  title_hbox.addWidget(QLabel(), 85, alignment=Qt.AlignCenter)
301
296
  title_hbox.addWidget(self.help_feature_btn, 5)
302
297
  title_hbox.addWidget(self.collapse_features_btn, 5)
303
- grid.addLayout(title_hbox, 0,0,1,4)
298
+ grid.addLayout(title_hbox, 0, 0, 1, 4)
304
299
 
305
300
  self.generate_feature_panel_contents()
306
301
  grid.addWidget(self.ContentsFeatures, 1, 0, 1, 4, alignment=Qt.AlignTop)
@@ -321,13 +316,13 @@ class ConfigTracking(QMainWindow, Styles):
321
316
  is_open = np.array([features_open, config_open, post_open])
322
317
 
323
318
  if self.ContentsFeatures.isHidden():
324
- self.collapse_features_btn.setIcon(icon(MDI6.chevron_down,color="black"))
319
+ self.collapse_features_btn.setIcon(icon(MDI6.chevron_down, color="black"))
325
320
  self.collapse_features_btn.setIconSize(QSize(20, 20))
326
321
  if len(is_open[is_open])==0:
327
322
  self.scroll_area.setMinimumHeight(int(self.minimum_height))
328
323
  self.adjustSize()
329
324
  else:
330
- self.collapse_features_btn.setIcon(icon(MDI6.chevron_up,color="black"))
325
+ self.collapse_features_btn.setIcon(icon(MDI6.chevron_up, color="black"))
331
326
  self.collapse_features_btn.setIconSize(QSize(20, 20))
332
327
  self.scroll_area.setMinimumHeight(min(int(930), int(0.9*self.screen_height)))
333
328
 
@@ -351,7 +346,7 @@ class ConfigTracking(QMainWindow, Styles):
351
346
  self.min_tracklength_slider.setSingleStep(1)
352
347
  self.min_tracklength_slider.setTickInterval(1)
353
348
  self.min_tracklength_slider.setSingleStep(1)
354
- self.min_tracklength_slider.setOrientation(1)
349
+ self.min_tracklength_slider.setOrientation(Qt.Horizontal)
355
350
  self.min_tracklength_slider.setRange(0,self.parent_window.parent_window.len_movie)
356
351
  self.min_tracklength_slider.setValue(0)
357
352
  tracklength_layout.addWidget(QLabel('Min. tracklength: '),40)
@@ -391,7 +386,6 @@ class ConfigTracking(QMainWindow, Styles):
391
386
 
392
387
  layout.addLayout(clean_traj_sublayout)
393
388
 
394
-
395
389
  def generate_feature_panel_contents(self):
396
390
 
397
391
  self.ContentsFeatures = QFrame()
@@ -456,10 +450,9 @@ class ConfigTracking(QMainWindow, Styles):
456
450
 
457
451
  # Slider to set vmin & vmax
458
452
  self.haralick_scale_slider = QLabeledDoubleSlider()
459
- self.haralick_scale_slider.setSingleStep(0.05)
460
453
  self.haralick_scale_slider.setTickInterval(0.05)
461
454
  self.haralick_scale_slider.setSingleStep(1)
462
- self.haralick_scale_slider.setOrientation(1)
455
+ self.haralick_scale_slider.setOrientation(Qt.Horizontal)
463
456
  self.haralick_scale_slider.setRange(0,1)
464
457
  self.haralick_scale_slider.setValue(0.5)
465
458
  self.haralick_scale_lbl = QLabel('Scale: ')
@@ -671,7 +664,7 @@ class ConfigTracking(QMainWindow, Styles):
671
664
  self.memory_slider.setSingleStep(1)
672
665
  self.memory_slider.setTickInterval(1)
673
666
  self.memory_slider.setSingleStep(1)
674
- self.memory_slider.setOrientation(1)
667
+ self.memory_slider.setOrientation(Qt.Horizontal)
675
668
  self.memory_slider.setRange(0,self.parent_window.parent_window.len_movie)
676
669
  self.memory_slider.setValue(0)
677
670
  memory_layout.addWidget(self.memory_lbl, 30)
@@ -745,7 +738,7 @@ class ConfigTracking(QMainWindow, Styles):
745
738
  copyfile(self.filename, self.config_path)
746
739
  self.load_cell_config()
747
740
  except Exception as e:
748
- print(e, modelpath)
741
+ print(e)
749
742
  return None
750
743
 
751
744
  def reset_btrack_config(self):
@@ -994,7 +987,7 @@ class ConfigTracking(QMainWindow, Styles):
994
987
  if 'search_range' in tracking_instructions:
995
988
  search_range = tracking_instructions['search_range']
996
989
  if search_range is not None:
997
- self.search_range_le.setText(str(search_range).replace('.',','))
990
+ self.search_range_le.setText(str(search_range).replace('.', ','))
998
991
  if 'memory' in tracking_instructions:
999
992
  memory = tracking_instructions['memory']
1000
993
  if memory is not None:
@@ -1072,7 +1065,7 @@ class ConfigTracking(QMainWindow, Styles):
1072
1065
  Load the first frame of the first movie found in the experiment folder as a sample.
1073
1066
  """
1074
1067
 
1075
- movies = glob(self.parent_window.parent_window.exp_dir + os.sep.join(["*","*","movie",self.parent_window.parent_window.movie_prefix+"*.tif"]))
1068
+ movies = glob(self.parent_window.parent_window.exp_dir + os.sep.join(["*", "*", "movie", self.parent_window.parent_window.movie_prefix+"*.tif"]))
1076
1069
  if len(movies)==0:
1077
1070
  msgBox = QMessageBox()
1078
1071
  msgBox.setIcon(QMessageBox.Warning)
@@ -1088,7 +1081,6 @@ class ConfigTracking(QMainWindow, Styles):
1088
1081
  n_channels = len(self.channels)
1089
1082
  self.test_frame = load_frames(np.arange(n_channels), stack0, scale=None, normalize_input=False)
1090
1083
 
1091
-
1092
1084
  def control_haralick_digitalization(self):
1093
1085
 
1094
1086
  """