celldetective 1.2.0__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.
- celldetective/__main__.py +12 -5
- celldetective/events.py +28 -2
- celldetective/gui/about.py +0 -1
- celldetective/gui/analyze_block.py +3 -18
- celldetective/gui/btrack_options.py +126 -21
- celldetective/gui/classifier_widget.py +68 -107
- celldetective/gui/configure_new_exp.py +37 -4
- celldetective/gui/control_panel.py +14 -30
- celldetective/gui/generic_signal_plot.py +793 -0
- celldetective/gui/gui_utils.py +401 -226
- celldetective/gui/json_readers.py +0 -2
- celldetective/gui/layouts.py +269 -25
- celldetective/gui/measurement_options.py +14 -23
- celldetective/gui/neighborhood_options.py +6 -16
- celldetective/gui/plot_measurements.py +10 -23
- celldetective/gui/plot_signals_ui.py +53 -687
- celldetective/gui/process_block.py +320 -186
- celldetective/gui/retrain_segmentation_model_options.py +30 -47
- celldetective/gui/retrain_signal_model_options.py +5 -14
- celldetective/gui/seg_model_loader.py +129 -113
- celldetective/gui/signal_annotator.py +93 -103
- celldetective/gui/signal_annotator2.py +9 -13
- celldetective/gui/styles.py +32 -0
- celldetective/gui/survival_ui.py +49 -712
- celldetective/gui/tableUI.py +4 -39
- celldetective/gui/thresholds_gui.py +38 -11
- celldetective/gui/viewers.py +6 -7
- celldetective/io.py +62 -84
- celldetective/measure.py +374 -15
- celldetective/models/segmentation_effectors/ricm-bimodal/config_input.json +130 -0
- celldetective/models/segmentation_effectors/ricm-bimodal/ricm-bimodal +0 -0
- celldetective/models/segmentation_effectors/ricm-bimodal/training_instructions.json +37 -0
- celldetective/neighborhood.py +3 -7
- celldetective/preprocessing.py +2 -4
- celldetective/relative_measurements.py +0 -3
- celldetective/scripts/analyze_signals.py +0 -1
- celldetective/scripts/measure_cells.py +1 -3
- celldetective/scripts/measure_relative.py +1 -2
- celldetective/scripts/segment_cells.py +16 -12
- celldetective/scripts/segment_cells_thresholds.py +17 -10
- celldetective/scripts/track_cells.py +18 -18
- celldetective/scripts/train_segmentation_model.py +1 -2
- celldetective/scripts/train_signal_model.py +0 -3
- celldetective/segmentation.py +1 -1
- celldetective/signals.py +20 -8
- celldetective/tracking.py +2 -1
- celldetective/utils.py +126 -18
- {celldetective-1.2.0.dist-info → celldetective-1.2.2.dist-info}/METADATA +19 -12
- celldetective-1.2.2.dist-info/RECORD +92 -0
- {celldetective-1.2.0.dist-info → celldetective-1.2.2.dist-info}/WHEEL +1 -1
- celldetective-1.2.0.dist-info/RECORD +0 -88
- {celldetective-1.2.0.dist-info → celldetective-1.2.2.dist-info}/LICENSE +0 -0
- {celldetective-1.2.0.dist-info → celldetective-1.2.2.dist-info}/entry_points.txt +0 -0
- {celldetective-1.2.0.dist-info → celldetective-1.2.2.dist-info}/top_level.txt +0 -0
celldetective/gui/survival_ui.py
CHANGED
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
from PyQt5.QtWidgets import
|
|
2
|
-
from PyQt5.QtCore import Qt
|
|
3
|
-
from PyQt5.QtGui import
|
|
4
|
-
from celldetective.gui.gui_utils import center_window
|
|
5
|
-
from superqt import
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from celldetective.
|
|
9
|
-
from celldetective.io import interpret_tracking_configuration, load_frames, auto_load_number_of_frames, load_experiment_tables
|
|
10
|
-
from celldetective.measure import compute_haralick_features, contour_of_instance_segmentation
|
|
1
|
+
from PyQt5.QtWidgets import QMessageBox, QComboBox, QLineEdit, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QPushButton
|
|
2
|
+
from PyQt5.QtCore import Qt
|
|
3
|
+
from PyQt5.QtGui import QDoubleValidator
|
|
4
|
+
from celldetective.gui.gui_utils import center_window
|
|
5
|
+
from superqt import QColormapComboBox
|
|
6
|
+
from celldetective.gui.generic_signal_plot import SurvivalPlotWidget
|
|
7
|
+
from celldetective.utils import get_software_location, _extract_labels_from_config
|
|
8
|
+
from celldetective.io import load_experiment_tables
|
|
11
9
|
import numpy as np
|
|
12
|
-
from tifffile import imread
|
|
13
|
-
import json
|
|
14
|
-
from shutil import copyfile
|
|
15
10
|
import os
|
|
16
11
|
import matplotlib.pyplot as plt
|
|
17
12
|
plt.rcParams['svg.fonttype'] = 'none'
|
|
18
|
-
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
|
19
13
|
from glob import glob
|
|
20
|
-
from natsort import natsorted
|
|
21
|
-
from tifffile import imread
|
|
22
|
-
from pathlib import Path, PurePath
|
|
23
|
-
import gc
|
|
24
14
|
import pandas as pd
|
|
25
|
-
from tqdm import tqdm
|
|
26
|
-
from lifelines import KaplanMeierFitter
|
|
27
|
-
import matplotlib.cm as mcm
|
|
28
|
-
import math
|
|
29
|
-
from celldetective.events import switch_to_events
|
|
30
15
|
from celldetective.gui import Styles
|
|
31
16
|
from matplotlib import colormaps
|
|
17
|
+
from celldetective.events import compute_survival
|
|
32
18
|
|
|
33
19
|
class ConfigSurvival(QWidget, Styles):
|
|
34
20
|
|
|
@@ -42,7 +28,7 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
42
28
|
super().__init__()
|
|
43
29
|
self.parent_window = parent_window
|
|
44
30
|
self.setWindowTitle("Configure survival")
|
|
45
|
-
self.setWindowIcon(
|
|
31
|
+
self.setWindowIcon(self.celldetective_icon)
|
|
46
32
|
|
|
47
33
|
self.exp_dir = self.parent_window.exp_dir
|
|
48
34
|
self.soft_path = get_software_location()
|
|
@@ -62,12 +48,10 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
62
48
|
center_window(self)
|
|
63
49
|
|
|
64
50
|
self.setMinimumWidth(350)
|
|
65
|
-
#self.setMinimumHeight(int(0.8*self.screen_height))
|
|
66
|
-
#self.setMaximumHeight(int(0.8*self.screen_height))
|
|
67
51
|
self.populate_widget()
|
|
68
|
-
#self.load_previous_measurement_instructions()
|
|
69
52
|
if self.auto_close:
|
|
70
53
|
self.close()
|
|
54
|
+
|
|
71
55
|
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
72
56
|
|
|
73
57
|
def interpret_pos_location(self):
|
|
@@ -110,7 +94,7 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
110
94
|
|
|
111
95
|
|
|
112
96
|
labels = [QLabel('population: '), QLabel('time of\nreference: '), QLabel('time of\ninterest: '), QLabel('cmap: ')] #QLabel('class: '),
|
|
113
|
-
self.cb_options = [['targets','effectors'], ['0'], [],
|
|
97
|
+
self.cb_options = [['targets','effectors'], ['0'], [], []] #['class'],
|
|
114
98
|
self.cbs = [QComboBox() for i in range(len(labels))]
|
|
115
99
|
|
|
116
100
|
self.cbs[-1] = QColormapComboBox()
|
|
@@ -126,7 +110,8 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
126
110
|
self.cbs[i].addItems(self.cb_options[i])
|
|
127
111
|
choice_layout.addLayout(hbox)
|
|
128
112
|
|
|
129
|
-
|
|
113
|
+
all_cms = list(colormaps)
|
|
114
|
+
for cm in all_cms:
|
|
130
115
|
try:
|
|
131
116
|
self.cbs[-1].addColormap(cm)
|
|
132
117
|
except:
|
|
@@ -171,15 +156,10 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
171
156
|
for tab in tables:
|
|
172
157
|
cols = pd.read_csv(tab, nrows=1,encoding_errors='ignore').columns.tolist()
|
|
173
158
|
self.all_columns.extend(cols)
|
|
159
|
+
|
|
174
160
|
self.all_columns = np.unique(self.all_columns)
|
|
175
161
|
#class_idx = np.array([s.startswith('class_') for s in self.all_columns])
|
|
176
162
|
time_idx = np.array([s.startswith('t_') for s in self.all_columns])
|
|
177
|
-
class_idx = np.array([s.startswith('class') for s in self.all_columns])
|
|
178
|
-
|
|
179
|
-
# class_columns = list(self.all_columns[class_idx])
|
|
180
|
-
# for c in ['class_id', 'class_color']:
|
|
181
|
-
# if c in class_columns:
|
|
182
|
-
# class_columns.remove(c)
|
|
183
163
|
|
|
184
164
|
try:
|
|
185
165
|
time_columns = list(self.all_columns[time_idx])
|
|
@@ -188,25 +168,13 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
188
168
|
self.auto_close = True
|
|
189
169
|
return None
|
|
190
170
|
|
|
191
|
-
try:
|
|
192
|
-
class_columns = list(self.all_columns[class_idx])
|
|
193
|
-
self.cbs[3].clear()
|
|
194
|
-
self.cbs[3].addItems(np.unique(self.cb_options[3]+class_columns))
|
|
195
|
-
except:
|
|
196
|
-
print('no column starts with class')
|
|
197
|
-
self.auto_close = True
|
|
198
|
-
return None
|
|
199
|
-
|
|
200
|
-
self.cbs[2].clear()
|
|
201
|
-
self.cbs[2].addItems(np.unique(self.cb_options[2]+time_columns))
|
|
202
|
-
|
|
203
171
|
self.cbs[1].clear()
|
|
204
172
|
self.cbs[1].addItems(np.unique(self.cb_options[1]+time_columns))
|
|
205
173
|
self.cbs[1].setCurrentText('t_firstdetection')
|
|
206
174
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
175
|
+
self.cbs[2].clear()
|
|
176
|
+
self.cbs[2].addItems(np.unique(self.cb_options[2]+time_columns))
|
|
177
|
+
|
|
210
178
|
|
|
211
179
|
def process_survival(self):
|
|
212
180
|
|
|
@@ -231,173 +199,31 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
231
199
|
self.df = self.df.query(query_text)
|
|
232
200
|
except Exception as e:
|
|
233
201
|
print(e, ' The query is misunderstood and will not be applied...')
|
|
234
|
-
|
|
235
|
-
self.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
# plot survival
|
|
239
|
-
self.survivalWidget = QWidget()
|
|
240
|
-
self.survivalWidget.setMinimumHeight(int(0.8*self.screen_height))
|
|
241
|
-
self.survivalWidget.setWindowTitle('survival')
|
|
242
|
-
self.plotvbox = QVBoxLayout(self.survivalWidget)
|
|
243
|
-
self.plotvbox.setContentsMargins(30,30,30,30)
|
|
244
|
-
self.survival_title = QLabel('Survival function')
|
|
245
|
-
self.survival_title.setStyleSheet("""
|
|
246
|
-
font-weight: bold;
|
|
247
|
-
padding: 0px;
|
|
248
|
-
""")
|
|
249
|
-
self.plotvbox.addWidget(self.survival_title, alignment=Qt.AlignCenter)
|
|
250
|
-
|
|
251
|
-
plot_buttons_hbox = QHBoxLayout()
|
|
252
|
-
plot_buttons_hbox.addWidget(QLabel(''),90, alignment=Qt.AlignLeft)
|
|
253
|
-
|
|
254
|
-
self.legend_btn = QPushButton('')
|
|
255
|
-
self.legend_btn.setIcon(icon(MDI6.text_box,color="black"))
|
|
256
|
-
self.legend_btn.setStyleSheet(self.button_select_all)
|
|
257
|
-
self.legend_btn.setToolTip('Show or hide the legend')
|
|
258
|
-
self.legend_visible = True
|
|
259
|
-
self.legend_btn.clicked.connect(self.show_hide_legend)
|
|
260
|
-
plot_buttons_hbox.addWidget(self.legend_btn, 5,alignment=Qt.AlignRight)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
self.log_btn = QPushButton('')
|
|
264
|
-
self.log_btn.setIcon(icon(MDI6.math_log,color="black"))
|
|
265
|
-
self.log_btn.setStyleSheet(self.button_select_all)
|
|
266
|
-
self.log_btn.clicked.connect(self.switch_to_log)
|
|
267
|
-
self.log_btn.setToolTip('Enable or disable log scale')
|
|
268
|
-
plot_buttons_hbox.addWidget(self.log_btn, 5, alignment=Qt.AlignRight)
|
|
269
|
-
|
|
270
|
-
self.fig, self.ax = plt.subplots(1,1,figsize=(4,3))
|
|
271
|
-
self.survival_window = FigureCanvas(self.fig, title="Survival")
|
|
272
|
-
self.survival_window.setContentsMargins(0,0,0,0)
|
|
273
|
-
if self.df is not None:
|
|
274
|
-
self.initialize_axis()
|
|
275
|
-
plt.tight_layout()
|
|
276
|
-
self.fig.set_facecolor('none') # or 'None'
|
|
277
|
-
self.fig.canvas.setStyleSheet("background-color: transparent;")
|
|
278
|
-
self.survival_window.canvas.draw()
|
|
279
|
-
|
|
280
|
-
#self.survival_window.layout.addWidget(QLabel('WHAAAAATTT???'))
|
|
281
|
-
|
|
282
|
-
self.plot_options = [QRadioButton() for i in range(3)]
|
|
283
|
-
self.radio_labels = ['well', 'pos', 'both']
|
|
284
|
-
radio_hbox = QHBoxLayout()
|
|
285
|
-
radio_hbox.setContentsMargins(30,30,30,30)
|
|
286
|
-
self.plot_btn_group = QButtonGroup()
|
|
287
|
-
for i in range(3):
|
|
288
|
-
self.plot_options[i].setText(self.radio_labels[i])
|
|
289
|
-
#self.plot_options[i].toggled.connect(self.plot_survivals)
|
|
290
|
-
self.plot_btn_group.addButton(self.plot_options[i])
|
|
291
|
-
radio_hbox.addWidget(self.plot_options[i], 33, alignment=Qt.AlignCenter)
|
|
292
|
-
self.plot_btn_group.buttonClicked[int].connect(self.plot_survivals)
|
|
293
|
-
|
|
294
|
-
if self.position_indices is not None:
|
|
295
|
-
if len(self.well_indices)>1 and len(self.position_indices)==1:
|
|
296
|
-
self.plot_btn_group.buttons()[0].click()
|
|
297
|
-
for i in [1,2]:
|
|
298
|
-
self.plot_options[i].setEnabled(False)
|
|
299
|
-
elif len(self.well_indices)>1:
|
|
300
|
-
self.plot_btn_group.buttons()[0].click()
|
|
301
|
-
elif len(self.well_indices)==1 and len(self.position_indices)==1:
|
|
302
|
-
self.plot_btn_group.buttons()[1].click()
|
|
303
|
-
for i in [0,2]:
|
|
304
|
-
self.plot_options[i].setEnabled(False)
|
|
202
|
+
|
|
203
|
+
self.interpret_pos_location()
|
|
204
|
+
if self.class_of_interest in list(self.df.columns) and self.cbs[2].currentText() in list(self.df.columns):
|
|
205
|
+
self.compute_survival_functions()
|
|
305
206
|
else:
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
self.plotvbox.addWidget(self.survival_window)
|
|
327
|
-
|
|
328
|
-
self.select_pos_label = QLabel('Select positions')
|
|
329
|
-
self.select_pos_label.setStyleSheet("""
|
|
330
|
-
font-weight: bold;
|
|
331
|
-
padding: 0px;
|
|
332
|
-
""")
|
|
333
|
-
self.plotvbox.addWidget(self.select_pos_label, alignment=Qt.AlignCenter)
|
|
334
|
-
|
|
335
|
-
self.select_option = [QRadioButton() for i in range(2)]
|
|
336
|
-
self.select_label = ['name', 'spatial']
|
|
337
|
-
select_hbox = QHBoxLayout()
|
|
338
|
-
select_hbox.setContentsMargins(30,30,30,30)
|
|
339
|
-
self.select_btn_group = QButtonGroup()
|
|
340
|
-
for i in range(2):
|
|
341
|
-
self.select_option[i].setText(self.select_label[i])
|
|
342
|
-
#self.select_option[i].toggled.connect(self.switch_selection_mode)
|
|
343
|
-
self.select_btn_group.addButton(self.select_option[i])
|
|
344
|
-
select_hbox.addWidget(self.select_option[i],33, alignment=Qt.AlignCenter)
|
|
345
|
-
self.select_btn_group.buttonClicked[int].connect(self.switch_selection_mode)
|
|
346
|
-
self.plotvbox.addLayout(select_hbox)
|
|
347
|
-
|
|
348
|
-
self.look_for_metadata()
|
|
349
|
-
if self.metadata_found:
|
|
350
|
-
self.fig_scatter, self.ax_scatter = plt.subplots(1,1,figsize=(4,3))
|
|
351
|
-
self.position_scatter = FigureCanvas(self.fig_scatter)
|
|
352
|
-
self.load_coordinates()
|
|
353
|
-
self.plot_spatial_location()
|
|
354
|
-
#self.plot_positions()
|
|
355
|
-
self.ax_scatter.spines['top'].set_visible(False)
|
|
356
|
-
self.ax_scatter.spines['right'].set_visible(False)
|
|
357
|
-
self.ax_scatter.set_aspect('equal')
|
|
358
|
-
self.ax_scatter.set_xticks([])
|
|
359
|
-
self.ax_scatter.set_yticks([])
|
|
360
|
-
plt.tight_layout()
|
|
361
|
-
self.fig_scatter.set_facecolor('none') # or 'None'
|
|
362
|
-
self.fig_scatter.canvas.setStyleSheet("background-color: transparent;")
|
|
363
|
-
self.plotvbox.addWidget(self.position_scatter)
|
|
364
|
-
|
|
365
|
-
self.generate_pos_selection_widget()
|
|
366
|
-
|
|
367
|
-
# if self.df is not None and len(self.ks_estimators_per_position)>0:
|
|
368
|
-
# self.plot_survivals()
|
|
369
|
-
self.select_btn_group.buttons()[0].click()
|
|
370
|
-
self.survivalWidget.show()
|
|
371
|
-
|
|
372
|
-
def generate_pos_selection_widget(self):
|
|
373
|
-
|
|
374
|
-
self.well_names = self.df['well_name'].unique()
|
|
375
|
-
self.pos_names = self.df_pos_info['pos_name'].unique() #pd.DataFrame(self.ks_estimators_per_position)['position_name'].unique()
|
|
376
|
-
print(f'POSITION NAMES: ',self.pos_names)
|
|
377
|
-
self.usable_well_labels = []
|
|
378
|
-
for name in self.well_names:
|
|
379
|
-
for lbl in self.well_labels:
|
|
380
|
-
if name+':' in lbl:
|
|
381
|
-
self.usable_well_labels.append(lbl)
|
|
382
|
-
|
|
383
|
-
self.line_choice_widget = QWidget()
|
|
384
|
-
self.line_check_vbox = QVBoxLayout()
|
|
385
|
-
self.line_choice_widget.setLayout(self.line_check_vbox)
|
|
386
|
-
if len(self.well_indices)>1:
|
|
387
|
-
self.well_display_options = [QCheckBox(self.usable_well_labels[i]) for i in range(len(self.usable_well_labels))]
|
|
388
|
-
for i in range(len(self.well_names)):
|
|
389
|
-
self.line_check_vbox.addWidget(self.well_display_options[i], alignment=Qt.AlignLeft)
|
|
390
|
-
self.well_display_options[i].setChecked(True)
|
|
391
|
-
self.well_display_options[i].toggled.connect(self.select_survival_lines)
|
|
392
|
-
else:
|
|
393
|
-
self.pos_display_options = [QCheckBox(self.pos_names[i]) for i in range(len(self.pos_names))]
|
|
394
|
-
for i in range(len(self.pos_names)):
|
|
395
|
-
self.line_check_vbox.addWidget(self.pos_display_options[i], alignment=Qt.AlignLeft)
|
|
396
|
-
self.pos_display_options[i].setChecked(True)
|
|
397
|
-
self.pos_display_options[i].toggled.connect(self.select_survival_lines)
|
|
398
|
-
|
|
399
|
-
self.plotvbox.addWidget(self.line_choice_widget, alignment=Qt.AlignCenter)
|
|
400
|
-
|
|
207
|
+
msgBox = QMessageBox()
|
|
208
|
+
msgBox.setIcon(QMessageBox.Warning)
|
|
209
|
+
msgBox.setText("The class and/or event time of interest is not found in the dataframe...")
|
|
210
|
+
msgBox.setWindowTitle("Warning")
|
|
211
|
+
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
212
|
+
returnValue = msgBox.exec()
|
|
213
|
+
if returnValue == QMessageBox.Ok:
|
|
214
|
+
return None
|
|
215
|
+
if 'survival_fit' in list(self.df_pos_info.columns):
|
|
216
|
+
self.plot_window = SurvivalPlotWidget(parent_window=self, df=self.df, df_pos_info = self.df_pos_info, df_well_info = self.df_well_info, title='plot survivals')
|
|
217
|
+
self.plot_window.show()
|
|
218
|
+
else:
|
|
219
|
+
msgBox = QMessageBox()
|
|
220
|
+
msgBox.setIcon(QMessageBox.Warning)
|
|
221
|
+
msgBox.setText("No survival function was successfully computed...\nCheck your parameter choice.")
|
|
222
|
+
msgBox.setWindowTitle("Warning")
|
|
223
|
+
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
224
|
+
returnValue = msgBox.exec()
|
|
225
|
+
if returnValue == QMessageBox.Ok:
|
|
226
|
+
return None
|
|
401
227
|
|
|
402
228
|
def load_available_tables_local(self):
|
|
403
229
|
|
|
@@ -426,9 +252,7 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
426
252
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
427
253
|
returnValue = msgBox.exec()
|
|
428
254
|
if returnValue == QMessageBox.Ok:
|
|
429
|
-
self.close()
|
|
430
255
|
return None
|
|
431
|
-
print('no table could be found...')
|
|
432
256
|
else:
|
|
433
257
|
self.df_well_info = self.df_pos_info.loc[:,['well_path', 'well_index', 'well_name', 'well_number', 'well_alias']].drop_duplicates()
|
|
434
258
|
#print(f"{self.df_well_info=}")
|
|
@@ -436,505 +260,18 @@ class ConfigSurvival(QWidget, Styles):
|
|
|
436
260
|
def compute_survival_functions(self):
|
|
437
261
|
|
|
438
262
|
# Per position survival
|
|
439
|
-
left_censored = False
|
|
440
263
|
for block,movie_group in self.df.groupby(['well','position']):
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
except Exception as e:
|
|
445
|
-
print(e)
|
|
446
|
-
continue
|
|
447
|
-
max_times = movie_group.groupby('TRACK_ID')['FRAME'].max().values
|
|
448
|
-
first_detections = None
|
|
449
|
-
|
|
450
|
-
if self.cbs[1].currentText()=='first detection':
|
|
451
|
-
left_censored = True
|
|
452
|
-
|
|
453
|
-
first_detections = []
|
|
454
|
-
for tid,track_group in movie_group.groupby('TRACK_ID'):
|
|
455
|
-
if 'area' in self.df.columns:
|
|
456
|
-
area = track_group['area'].values
|
|
457
|
-
timeline = track_group['FRAME'].values
|
|
458
|
-
if np.any(area==area):
|
|
459
|
-
first_det = timeline[area==area][0]
|
|
460
|
-
first_detections.append(first_det)
|
|
461
|
-
else:
|
|
462
|
-
# think about assymmetry with class and times
|
|
463
|
-
continue
|
|
464
|
-
else:
|
|
465
|
-
continue
|
|
466
|
-
|
|
467
|
-
elif self.cbs[1].currentText().startswith('t'):
|
|
468
|
-
left_censored = True
|
|
469
|
-
first_detections = movie_group.groupby('TRACK_ID')[self.cbs[1].currentText()].max().values
|
|
470
|
-
print(first_detections)
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if self.cbs[1].currentText()=='first detection' or self.cbs[1].currentText().startswith('t'):
|
|
474
|
-
left_censored = True
|
|
475
|
-
else:
|
|
476
|
-
left_censored = False
|
|
477
|
-
events, survival_times = switch_to_events(classes, times, max_times, first_detections, left_censored=left_censored, FrameToMin=self.FrameToMin)
|
|
478
|
-
ks = KaplanMeierFitter()
|
|
479
|
-
if len(events)>0:
|
|
480
|
-
ks.fit(survival_times, event_observed=events)
|
|
264
|
+
|
|
265
|
+
ks = compute_survival(movie_group, self.class_of_interest, self.cbs[2].currentText(), t_reference=self.cbs[1].currentText(), FrameToMin=self.FrameToMin)
|
|
266
|
+
if ks is not None:
|
|
481
267
|
self.df_pos_info.loc[self.df_pos_info['pos_path']==block[1],'survival_fit'] = ks
|
|
482
268
|
|
|
483
269
|
# Per well survival
|
|
484
|
-
left_censored = False
|
|
485
270
|
for well,well_group in self.df.groupby('well'):
|
|
486
271
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
well_first_detections = []
|
|
491
|
-
|
|
492
|
-
for block,movie_group in well_group.groupby('position'):
|
|
493
|
-
try:
|
|
494
|
-
classes = movie_group.groupby('TRACK_ID')[self.class_of_interest].min().values
|
|
495
|
-
times = movie_group.groupby('TRACK_ID')[self.cbs[2].currentText()].min().values
|
|
496
|
-
except Exception as e:
|
|
497
|
-
print(e)
|
|
498
|
-
continue
|
|
499
|
-
max_times = movie_group.groupby('TRACK_ID')['FRAME'].max().values
|
|
500
|
-
first_detections = None
|
|
501
|
-
|
|
502
|
-
if self.cbs[1].currentText()=='first detection':
|
|
503
|
-
|
|
504
|
-
left_censored = True
|
|
505
|
-
first_detections = []
|
|
506
|
-
for tid,track_group in movie_group.groupby('TRACK_ID'):
|
|
507
|
-
if 'area' in self.df.columns:
|
|
508
|
-
area = track_group['area'].values
|
|
509
|
-
timeline = track_group['FRAME'].values
|
|
510
|
-
if np.any(area==area):
|
|
511
|
-
first_det = timeline[area==area][0]
|
|
512
|
-
first_detections.append(first_det)
|
|
513
|
-
else:
|
|
514
|
-
# think about assymmetry with class and times
|
|
515
|
-
continue
|
|
516
|
-
|
|
517
|
-
elif self.cbs[1].currentText().startswith('t'):
|
|
518
|
-
left_censored = True
|
|
519
|
-
first_detections = movie_group.groupby('TRACK_ID')[self.cbs[1].currentText()].max().values
|
|
520
|
-
|
|
521
|
-
else:
|
|
522
|
-
pass
|
|
523
|
-
|
|
524
|
-
well_classes.extend(classes)
|
|
525
|
-
well_times.extend(times)
|
|
526
|
-
well_max_times.extend(max_times)
|
|
527
|
-
if first_detections is not None:
|
|
528
|
-
well_first_detections.extend(first_detections)
|
|
529
|
-
|
|
530
|
-
if len(well_first_detections)==0:
|
|
531
|
-
well_first_detections = None
|
|
532
|
-
|
|
533
|
-
print(f"{well_classes=}; {well_times=}")
|
|
534
|
-
events, survival_times = switch_to_events(well_classes, well_times, well_max_times, well_first_detections,left_censored=left_censored, FrameToMin=self.FrameToMin)
|
|
535
|
-
print(f"{events=}; {survival_times=}")
|
|
536
|
-
ks = KaplanMeierFitter()
|
|
537
|
-
if len(survival_times)>0:
|
|
538
|
-
ks.fit(survival_times, event_observed=events)
|
|
539
|
-
print(ks.survival_function_)
|
|
540
|
-
else:
|
|
541
|
-
ks = None
|
|
542
|
-
print(f"{ks=}")
|
|
543
|
-
self.df_well_info.loc[self.df_well_info['well_path']==well,'survival_fit'] = ks
|
|
272
|
+
ks = compute_survival(well_group, self.class_of_interest, self.cbs[2].currentText(), t_reference=self.cbs[1].currentText(), FrameToMin=self.FrameToMin)
|
|
273
|
+
if ks is not None:
|
|
274
|
+
self.df_well_info.loc[self.df_well_info['well_path']==well,'survival_fit'] = ks
|
|
544
275
|
|
|
545
276
|
self.df_pos_info.loc[:,'select'] = True
|
|
546
|
-
self.df_well_info.loc[:,'select'] = True
|
|
547
|
-
|
|
548
|
-
def initialize_axis(self):
|
|
549
|
-
|
|
550
|
-
self.ax.clear()
|
|
551
|
-
self.ax.plot([],[])
|
|
552
|
-
self.ax.spines['top'].set_visible(False)
|
|
553
|
-
self.ax.spines['right'].set_visible(False)
|
|
554
|
-
#self.ax.set_ylim(0.001,1.05)
|
|
555
|
-
self.ax.set_xlim(0,self.df['FRAME'].max()*self.FrameToMin)
|
|
556
|
-
self.ax.set_xlabel('time [min]')
|
|
557
|
-
self.ax.set_ylabel('survival')
|
|
558
|
-
|
|
559
|
-
def plot_survivals(self, id):
|
|
560
|
-
|
|
561
|
-
for i in range(3):
|
|
562
|
-
if self.plot_options[i].isChecked():
|
|
563
|
-
self.plot_mode = self.radio_labels[i]
|
|
564
|
-
|
|
565
|
-
cmap_lbl = self.cbs[-1].currentText()
|
|
566
|
-
self.cmap = getattr(mcm, cmap_lbl)
|
|
567
|
-
|
|
568
|
-
colors = np.array([self.cmap(i / len(self.df_pos_info)) for i in range(len(self.df_pos_info))])
|
|
569
|
-
well_color = [self.cmap(i / len(self.df_well_info)) for i in range(len(self.df_well_info))]
|
|
570
|
-
|
|
571
|
-
if self.plot_mode=='pos':
|
|
572
|
-
self.initialize_axis()
|
|
573
|
-
lines = self.df_pos_info.loc[self.df_pos_info['select'],'survival_fit'].values
|
|
574
|
-
pos_labels = self.df_pos_info.loc[self.df_pos_info['select'],'pos_name'].values
|
|
575
|
-
pos_indices = self.df_pos_info.loc[self.df_pos_info['select'],'pos_index'].values
|
|
576
|
-
well_index = self.df_pos_info.loc[self.df_pos_info['select'],'well_index'].values
|
|
577
|
-
for i in range(len(lines)):
|
|
578
|
-
if (len(self.well_indices)<=1) and lines[i]==lines[i]:
|
|
579
|
-
try:
|
|
580
|
-
lines[i].plot_survival_function(ax=self.ax, legend=None, color=colors[pos_indices[i]],label=pos_labels[i], xlabel='timeline [min]')
|
|
581
|
-
except Exception as e:
|
|
582
|
-
print(f'error {e}')
|
|
583
|
-
pass
|
|
584
|
-
elif lines[i]==lines[i]:
|
|
585
|
-
try:
|
|
586
|
-
lines[i].plot_survival_function(ax=self.ax, legend=None, color=well_color[well_index[i]],label=pos_labels[i], xlabel='timeline [min]')
|
|
587
|
-
except Exception as e:
|
|
588
|
-
print(f'error {e}')
|
|
589
|
-
pass
|
|
590
|
-
else:
|
|
591
|
-
pass
|
|
592
|
-
|
|
593
|
-
elif self.plot_mode=='well':
|
|
594
|
-
self.initialize_axis()
|
|
595
|
-
lines = self.df_well_info.loc[self.df_well_info['select'],'survival_fit'].values
|
|
596
|
-
well_index = self.df_well_info.loc[self.df_well_info['select'],'well_index'].values
|
|
597
|
-
well_labels = self.df_well_info.loc[self.df_well_info['select'],'well_name'].values
|
|
598
|
-
for i in range(len(lines)):
|
|
599
|
-
if len(self.well_indices)<=1 and lines[i]==lines[i]:
|
|
600
|
-
|
|
601
|
-
try:
|
|
602
|
-
lines[i].plot_survival_function(ax=self.ax, label=well_labels[i], color="k", xlabel='timeline [min]')
|
|
603
|
-
except Exception as e:
|
|
604
|
-
print(f'error {e}')
|
|
605
|
-
pass
|
|
606
|
-
elif lines[i]==lines[i]:
|
|
607
|
-
try:
|
|
608
|
-
lines[i].plot_survival_function(ax=self.ax, label=well_labels[i], color=well_color[well_index[i]], xlabel='timeline [min]')
|
|
609
|
-
except Exception as e:
|
|
610
|
-
print(f'error {e}')
|
|
611
|
-
pass
|
|
612
|
-
else:
|
|
613
|
-
pass
|
|
614
|
-
|
|
615
|
-
elif self.plot_mode=='both':
|
|
616
|
-
self.initialize_axis()
|
|
617
|
-
if 'survival_fit' in self.df_pos_info.columns:
|
|
618
|
-
lines_pos = self.df_pos_info.loc[self.df_pos_info['select'],'survival_fit'].values
|
|
619
|
-
else:
|
|
620
|
-
lines_pos = []
|
|
621
|
-
if 'survival_fit' in self.df_well_info.columns:
|
|
622
|
-
lines_well = self.df_well_info.loc[self.df_well_info['select'],'survival_fit'].values
|
|
623
|
-
else:
|
|
624
|
-
lines_well = []
|
|
625
|
-
|
|
626
|
-
pos_indices = self.df_pos_info.loc[self.df_pos_info['select'],'pos_index'].values
|
|
627
|
-
well_index_pos = self.df_pos_info.loc[self.df_pos_info['select'],'well_index'].values
|
|
628
|
-
well_index = self.df_well_info.loc[self.df_well_info['select'],'well_index'].values
|
|
629
|
-
well_labels = self.df_well_info.loc[self.df_well_info['select'],'well_name'].values
|
|
630
|
-
pos_labels = self.df_pos_info.loc[self.df_pos_info['select'],'pos_name'].values
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
for i in range(len(lines_pos)):
|
|
634
|
-
if len(self.well_indices)<=1 and lines_pos[i]==lines_pos[i]:
|
|
635
|
-
|
|
636
|
-
try:
|
|
637
|
-
lines_pos[i].plot_survival_function(ax=self.ax, label=pos_labels[i], alpha=0.25, color=colors[pos_indices[i]], xlabel='timeline [min]')
|
|
638
|
-
except Exception as e:
|
|
639
|
-
print(f'error {e}')
|
|
640
|
-
pass
|
|
641
|
-
elif lines_pos[i]==lines_pos[i]:
|
|
642
|
-
try:
|
|
643
|
-
lines_pos[i].plot_survival_function(ci_show=False, ax=self.ax, legend=None, alpha=0.25, color=well_color[well_index_pos[i]], xlabel='timeline [min]')
|
|
644
|
-
except Exception as e:
|
|
645
|
-
print(f'error {e}')
|
|
646
|
-
pass
|
|
647
|
-
else:
|
|
648
|
-
pass
|
|
649
|
-
|
|
650
|
-
for i in range(len(lines_well)):
|
|
651
|
-
|
|
652
|
-
if len(self.well_indices)<=1 and lines_well[i]==lines_well[i]:
|
|
653
|
-
try:
|
|
654
|
-
lines_well[i].plot_survival_function(ax=self.ax, label='pool', color="k")
|
|
655
|
-
except Exception as e:
|
|
656
|
-
print(f'error {e}')
|
|
657
|
-
pass
|
|
658
|
-
elif lines_well[i]==lines_well[i]:
|
|
659
|
-
try:
|
|
660
|
-
lines_well[i].plot_survival_function(ax=self.ax, label=well_labels[i], color=well_color[well_index[i]])
|
|
661
|
-
except Exception as e:
|
|
662
|
-
print(f'error {e}')
|
|
663
|
-
pass
|
|
664
|
-
else:
|
|
665
|
-
pass
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
self.survival_window.canvas.draw()
|
|
669
|
-
|
|
670
|
-
def switch_to_log(self):
|
|
671
|
-
|
|
672
|
-
"""
|
|
673
|
-
Switch threshold histogram to log scale. Auto adjust.
|
|
674
|
-
"""
|
|
675
|
-
|
|
676
|
-
if self.ax.get_yscale()=='linear':
|
|
677
|
-
self.ax.set_yscale('log')
|
|
678
|
-
#self.ax.set_ylim(0.01,1.05)
|
|
679
|
-
else:
|
|
680
|
-
self.ax.set_yscale('linear')
|
|
681
|
-
#self.ax.set_ylim(0.01,1.05)
|
|
682
|
-
|
|
683
|
-
#self.ax.autoscale()
|
|
684
|
-
self.survival_window.canvas.draw_idle()
|
|
685
|
-
|
|
686
|
-
def show_hide_legend(self):
|
|
687
|
-
if self.legend_visible:
|
|
688
|
-
self.ax.legend().set_visible(False)
|
|
689
|
-
self.legend_visible = False
|
|
690
|
-
self.legend_btn.setIcon(icon(MDI6.text_box_outline,color="black"))
|
|
691
|
-
else:
|
|
692
|
-
self.ax.legend().set_visible(True)
|
|
693
|
-
self.legend_visible = True
|
|
694
|
-
self.legend_btn.setIcon(icon(MDI6.text_box,color="black"))
|
|
695
|
-
|
|
696
|
-
self.survival_window.canvas.draw_idle()
|
|
697
|
-
|
|
698
|
-
def look_for_metadata(self):
|
|
699
|
-
|
|
700
|
-
self.metadata_found = False
|
|
701
|
-
self.metafiles = glob(self.exp_dir+os.sep.join([f'W*','*','movie','*metadata.txt'])) \
|
|
702
|
-
+ glob(self.exp_dir+os.sep.join([f'W*','*','*metadata.txt'])) \
|
|
703
|
-
+ glob(self.exp_dir+os.sep.join([f'W*','*metadata.txt'])) \
|
|
704
|
-
+ glob(self.exp_dir+'*metadata.txt')
|
|
705
|
-
print(f'Found {len(self.metafiles)} metadata files...')
|
|
706
|
-
if len(self.metafiles)>0:
|
|
707
|
-
self.metadata_found = True
|
|
708
|
-
|
|
709
|
-
def switch_selection_mode(self, id):
|
|
710
|
-
print(f'button {id} was clicked')
|
|
711
|
-
for i in range(2):
|
|
712
|
-
if self.select_option[i].isChecked():
|
|
713
|
-
self.selection_mode = self.select_label[i]
|
|
714
|
-
if self.selection_mode=='name':
|
|
715
|
-
if len(self.metafiles)>0:
|
|
716
|
-
self.position_scatter.hide()
|
|
717
|
-
self.line_choice_widget.show()
|
|
718
|
-
else:
|
|
719
|
-
if len(self.metafiles)>0:
|
|
720
|
-
self.position_scatter.show()
|
|
721
|
-
self.line_choice_widget.hide()
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
def load_coordinates(self):
|
|
725
|
-
|
|
726
|
-
"""
|
|
727
|
-
Read metadata and try to extract position coordinates
|
|
728
|
-
"""
|
|
729
|
-
|
|
730
|
-
self.no_meta = False
|
|
731
|
-
try:
|
|
732
|
-
with open(self.metafiles[0], 'r') as f:
|
|
733
|
-
data = json.load(f)
|
|
734
|
-
positions = data['Summary']['InitialPositionList']
|
|
735
|
-
except Exception as e:
|
|
736
|
-
print(f'Trouble loading metadata: error {e}...')
|
|
737
|
-
return None
|
|
738
|
-
|
|
739
|
-
for k in range(len(positions)):
|
|
740
|
-
pos_label = positions[k]['Label']
|
|
741
|
-
try:
|
|
742
|
-
coords = positions[k]['DeviceCoordinatesUm']['XYStage']
|
|
743
|
-
except:
|
|
744
|
-
try:
|
|
745
|
-
coords = positions[k]['DeviceCoordinatesUm']['PIXYStage']
|
|
746
|
-
except:
|
|
747
|
-
self.no_meta = True
|
|
748
|
-
|
|
749
|
-
if not self.no_meta:
|
|
750
|
-
self.df_pos_info = self.df_pos_info.dropna(subset=['stack_path'])
|
|
751
|
-
files = self.df_pos_info['stack_path'].values
|
|
752
|
-
print(files)
|
|
753
|
-
pos_loc = [pos_label in f for f in files]
|
|
754
|
-
self.df_pos_info.loc[pos_loc, 'x'] = coords[0]
|
|
755
|
-
self.df_pos_info.loc[pos_loc, 'y'] = coords[1]
|
|
756
|
-
self.df_pos_info.loc[pos_loc, 'metadata_tag'] = pos_label
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
def update_annot(self, ind):
|
|
760
|
-
|
|
761
|
-
pos = self.sc.get_offsets()[ind["ind"][0]]
|
|
762
|
-
self.annot.xy = pos
|
|
763
|
-
text = self.scat_labels[ind["ind"][0]]
|
|
764
|
-
self.annot.set_text(text)
|
|
765
|
-
self.annot.get_bbox_patch().set_facecolor('k')
|
|
766
|
-
self.annot.get_bbox_patch().set_alpha(0.4)
|
|
767
|
-
|
|
768
|
-
def hover(self, event):
|
|
769
|
-
vis = self.annot.get_visible()
|
|
770
|
-
if event.inaxes == self.ax_scatter:
|
|
771
|
-
cont, ind = self.sc.contains(event)
|
|
772
|
-
if cont:
|
|
773
|
-
self.update_annot(ind)
|
|
774
|
-
self.annot.set_visible(True)
|
|
775
|
-
self.fig_scatter.canvas.draw_idle()
|
|
776
|
-
else:
|
|
777
|
-
if vis:
|
|
778
|
-
self.annot.set_visible(False)
|
|
779
|
-
self.fig_scatter.canvas.draw_idle()
|
|
780
|
-
|
|
781
|
-
def unselect_position(self, event):
|
|
782
|
-
|
|
783
|
-
ind = event.ind # index of selected position
|
|
784
|
-
well_idx = self.df_pos_info.iloc[ind]['well_index'].values[0]
|
|
785
|
-
selectedPos = self.df_pos_info.iloc[ind]['pos_path'].values[0]
|
|
786
|
-
currentSelState = self.df_pos_info.iloc[ind]['select'].values[0]
|
|
787
|
-
if self.plot_options[0].isChecked() or self.plot_options[2].isChecked():
|
|
788
|
-
self.df_pos_info.loc[self.df_pos_info['well_index']==well_idx,'select'] = not currentSelState
|
|
789
|
-
self.df_well_info.loc[self.df_well_info['well_index']==well_idx, 'select'] = not currentSelState
|
|
790
|
-
if len(self.well_indices)>1:
|
|
791
|
-
self.well_display_options[well_idx].setChecked(not currentSelState)
|
|
792
|
-
else:
|
|
793
|
-
for p in self.pos_display_options:
|
|
794
|
-
p.setChecked(not currentSelState)
|
|
795
|
-
else:
|
|
796
|
-
self.df_pos_info.loc[self.df_pos_info['pos_path']==selectedPos,'select'] = not currentSelState
|
|
797
|
-
if len(self.well_indices)<=1:
|
|
798
|
-
self.pos_display_options[ind[0]].setChecked(not currentSelState)
|
|
799
|
-
|
|
800
|
-
self.sc.set_color(self.select_color(self.df_pos_info["select"].values))
|
|
801
|
-
self.position_scatter.canvas.draw_idle()
|
|
802
|
-
self.plot_survivals(0)
|
|
803
|
-
|
|
804
|
-
def select_survival_lines(self):
|
|
805
|
-
|
|
806
|
-
if len(self.well_indices)>1:
|
|
807
|
-
for i in range(len(self.well_display_options)):
|
|
808
|
-
self.df_well_info.loc[self.df_well_info['well_index']==i,'select'] = self.well_display_options[i].isChecked()
|
|
809
|
-
self.df_pos_info.loc[self.df_pos_info['well_index']==i,'select'] = self.well_display_options[i].isChecked()
|
|
810
|
-
else:
|
|
811
|
-
for i in range(len(self.pos_display_options)):
|
|
812
|
-
self.df_pos_info.loc[self.df_pos_info['pos_index']==i,'select'] = self.pos_display_options[i].isChecked()
|
|
813
|
-
|
|
814
|
-
if len(self.metafiles)>0:
|
|
815
|
-
try:
|
|
816
|
-
self.sc.set_color(self.select_color(self.df_pos_info["select"].values))
|
|
817
|
-
self.position_scatter.canvas.draw_idle()
|
|
818
|
-
except:
|
|
819
|
-
pass
|
|
820
|
-
self.plot_survivals(0)
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
def select_color(self, selection):
|
|
824
|
-
colors = [self.cmap(0) if s else self.cmap(0.1) for s in selection]
|
|
825
|
-
return colors
|
|
826
|
-
|
|
827
|
-
def plot_spatial_location(self):
|
|
828
|
-
|
|
829
|
-
try:
|
|
830
|
-
self.sc = self.ax_scatter.scatter(self.df_pos_info["x"].values, self.df_pos_info["y"].values, picker=True, pickradius=1, color=self.select_color(self.df_pos_info["select"].values))
|
|
831
|
-
self.scat_labels = self.df_pos_info['metadata_tag'].values
|
|
832
|
-
self.ax_scatter.invert_xaxis()
|
|
833
|
-
self.annot = self.ax_scatter.annotate("", xy=(0,0), xytext=(10,10),textcoords="offset points",
|
|
834
|
-
bbox=dict(boxstyle="round", fc="w"),
|
|
835
|
-
arrowprops=dict(arrowstyle="->"))
|
|
836
|
-
self.annot.set_visible(False)
|
|
837
|
-
self.fig_scatter.canvas.mpl_connect("motion_notify_event", self.hover)
|
|
838
|
-
self.fig_scatter.canvas.mpl_connect("pick_event", self.unselect_position)
|
|
839
|
-
except Exception as e:
|
|
840
|
-
pass
|
|
841
|
-
|
|
842
|
-
# def plot_positions(self):
|
|
843
|
-
|
|
844
|
-
# # Load metadata, read X-Y positions
|
|
845
|
-
# coordinates = []
|
|
846
|
-
# line_index = []
|
|
847
|
-
# label_annotations = []
|
|
848
|
-
# coords_wells = []
|
|
849
|
-
# for m in self.metafiles[:1]:
|
|
850
|
-
# with open(m, 'r') as f:
|
|
851
|
-
# data = json.load(f)
|
|
852
|
-
# positions = data['Summary']['InitialPositionList']
|
|
853
|
-
# for k in range(len(positions)):
|
|
854
|
-
# pos_label = positions[k]['Label']
|
|
855
|
-
# coords = positions[k]['DeviceCoordinatesUm']['XYStage']
|
|
856
|
-
# for k,ks in enumerate(self.ks_estimators_per_position):
|
|
857
|
-
# pos = ks['position']
|
|
858
|
-
# pos_blocks = pos.split(os.sep)
|
|
859
|
-
# pos_blocks.remove('')
|
|
860
|
-
# well_id = pos_blocks[-3]
|
|
861
|
-
# movies = glob(pos+f'movie{os.sep}{self.parent.parent.movie_prefix}*.tif')
|
|
862
|
-
# if len(movies)>0:
|
|
863
|
-
# file = movies[0]
|
|
864
|
-
# if pos_label in file:
|
|
865
|
-
# print(f"match for index {k} between position {pos} and coordinates {pos_label}")
|
|
866
|
-
# coordinates.append(coords)
|
|
867
|
-
# line_index.append(k)
|
|
868
|
-
# label_annotations.append(pos_label)
|
|
869
|
-
# coords_wells.append({'x': coords[0], 'y': coords[1], 'well': well_id})
|
|
870
|
-
|
|
871
|
-
# coords_wells = pd.DataFrame(coords_wells)
|
|
872
|
-
# well_coordinates = coords_wells.groupby('well').mean()[['x','y']].to_numpy()
|
|
873
|
-
|
|
874
|
-
# coordinates = np.array(coordinates)
|
|
875
|
-
|
|
876
|
-
# if self.plot_options[0].isChecked():
|
|
877
|
-
# label_annotations_scat = list(coords_wells.groupby('well').mean().index)
|
|
878
|
-
# self.position_colors = [tab10(0) for i in range(len(well_coordinates))]
|
|
879
|
-
# self.sc = self.ax_scatter.scatter(well_coordinates[:,0], well_coordinates[:,1],picker=True, pickradius=1, color=self.position_colors)
|
|
880
|
-
|
|
881
|
-
# elif self.plot_options[1].isChecked():
|
|
882
|
-
# label_annotations_scat = label_annotations
|
|
883
|
-
# self.position_colors = [tab10(0) for i in range(len(coordinates))]
|
|
884
|
-
# self.sc = self.ax_scatter.scatter(coordinates[:,0], coordinates[:,1],picker=True, pickradius=1, color=self.position_colors)
|
|
885
|
-
|
|
886
|
-
# self.ax_scatter.invert_xaxis()
|
|
887
|
-
# annot = self.ax_scatter.annotate("", xy=(0,0), xytext=(10,10),textcoords="offset points",
|
|
888
|
-
# bbox=dict(boxstyle="round", fc="w"),
|
|
889
|
-
# arrowprops=dict(arrowstyle="->"))
|
|
890
|
-
# annot.set_visible(False)
|
|
891
|
-
|
|
892
|
-
# def update_annot(ind):
|
|
893
|
-
|
|
894
|
-
# pos = self.sc.get_offsets()[ind["ind"][0]]
|
|
895
|
-
# annot.xy = pos
|
|
896
|
-
# text = label_annotations_scat[ind["ind"][0]]
|
|
897
|
-
# # text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))),
|
|
898
|
-
# # " ".join([label_annotations[n] for n in ind["ind"]]))
|
|
899
|
-
# annot.set_text(text)
|
|
900
|
-
# annot.get_bbox_patch().set_facecolor('k')
|
|
901
|
-
# annot.get_bbox_patch().set_alpha(0.4)
|
|
902
|
-
|
|
903
|
-
# def hover(event):
|
|
904
|
-
# vis = annot.get_visible()
|
|
905
|
-
# if event.inaxes == self.ax_scatter:
|
|
906
|
-
# cont, ind = self.sc.contains(event)
|
|
907
|
-
# if cont:
|
|
908
|
-
# update_annot(ind)
|
|
909
|
-
# annot.set_visible(True)
|
|
910
|
-
# self.fig_scatter.canvas.draw_idle()
|
|
911
|
-
# else:
|
|
912
|
-
# if vis:
|
|
913
|
-
# annot.set_visible(False)
|
|
914
|
-
# self.fig_scatter.canvas.draw_idle()
|
|
915
|
-
|
|
916
|
-
# def unselect_position(event):
|
|
917
|
-
# print(event)
|
|
918
|
-
# ind = event.ind
|
|
919
|
-
# print(ind)
|
|
920
|
-
# if len(ind)>0:
|
|
921
|
-
# ind = ind[0]
|
|
922
|
-
# if self.position_colors[ind]==tab10(0.1):
|
|
923
|
-
# self.position_colors[ind] = tab10(0)
|
|
924
|
-
# if self.plot_options[1].isChecked():
|
|
925
|
-
# self.line_to_plot[ind] = True # reselect line
|
|
926
|
-
# elif self.plot_options[0].isChecked():
|
|
927
|
-
# self.line_to_plot_well[ind] = True
|
|
928
|
-
# else:
|
|
929
|
-
# self.position_colors[ind] = tab10(0.1)
|
|
930
|
-
# if self.plot_options[1].isChecked():
|
|
931
|
-
# self.line_to_plot[ind] = False # unselect line
|
|
932
|
-
# elif self.plot_options[0].isChecked():
|
|
933
|
-
# self.line_to_plot_well[ind] = False
|
|
934
|
-
# self.sc.set_color(self.position_colors)
|
|
935
|
-
# self.position_scatter.canvas.draw_idle()
|
|
936
|
-
# self.plot_survivals(0)
|
|
937
|
-
|
|
938
|
-
# self.fig_scatter.canvas.mpl_connect("motion_notify_event", hover)
|
|
939
|
-
# self.fig_scatter.canvas.mpl_connect("pick_event", unselect_position)
|
|
940
|
-
|
|
277
|
+
self.df_well_info.loc[:,'select'] = True
|