celldetective 1.4.2__py3-none-any.whl → 1.5.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- celldetective/__init__.py +25 -0
- celldetective/__main__.py +62 -43
- celldetective/_version.py +1 -1
- celldetective/extra_properties.py +477 -399
- celldetective/filters.py +192 -97
- celldetective/gui/InitWindow.py +541 -411
- celldetective/gui/__init__.py +0 -15
- celldetective/gui/about.py +44 -39
- celldetective/gui/analyze_block.py +120 -84
- celldetective/gui/base/__init__.py +0 -0
- celldetective/gui/base/channel_norm_generator.py +335 -0
- celldetective/gui/base/components.py +249 -0
- celldetective/gui/base/feature_choice.py +92 -0
- celldetective/gui/base/figure_canvas.py +52 -0
- celldetective/gui/base/list_widget.py +133 -0
- celldetective/gui/{styles.py → base/styles.py} +92 -36
- celldetective/gui/base/utils.py +33 -0
- celldetective/gui/base_annotator.py +900 -767
- celldetective/gui/classifier_widget.py +6 -22
- celldetective/gui/configure_new_exp.py +777 -671
- celldetective/gui/control_panel.py +635 -524
- celldetective/gui/dynamic_progress.py +449 -0
- celldetective/gui/event_annotator.py +2023 -1662
- celldetective/gui/generic_signal_plot.py +1292 -944
- celldetective/gui/gui_utils.py +899 -1289
- celldetective/gui/interactions_block.py +658 -0
- celldetective/gui/interactive_timeseries_viewer.py +447 -0
- celldetective/gui/json_readers.py +48 -15
- celldetective/gui/layouts/__init__.py +5 -0
- celldetective/gui/layouts/background_model_free_layout.py +537 -0
- celldetective/gui/layouts/channel_offset_layout.py +134 -0
- celldetective/gui/layouts/local_correction_layout.py +91 -0
- celldetective/gui/layouts/model_fit_layout.py +372 -0
- celldetective/gui/layouts/operation_layout.py +68 -0
- celldetective/gui/layouts/protocol_designer_layout.py +96 -0
- celldetective/gui/pair_event_annotator.py +3130 -2435
- celldetective/gui/plot_measurements.py +586 -267
- celldetective/gui/plot_signals_ui.py +724 -506
- celldetective/gui/preprocessing_block.py +395 -0
- celldetective/gui/process_block.py +1678 -1831
- celldetective/gui/seg_model_loader.py +580 -473
- celldetective/gui/settings/__init__.py +0 -7
- celldetective/gui/settings/_cellpose_model_params.py +181 -0
- celldetective/gui/settings/_event_detection_model_params.py +95 -0
- celldetective/gui/settings/_segmentation_model_params.py +159 -0
- celldetective/gui/settings/_settings_base.py +77 -65
- celldetective/gui/settings/_settings_event_model_training.py +752 -526
- celldetective/gui/settings/_settings_measurements.py +1133 -964
- celldetective/gui/settings/_settings_neighborhood.py +574 -488
- celldetective/gui/settings/_settings_segmentation_model_training.py +779 -564
- celldetective/gui/settings/_settings_signal_annotator.py +329 -305
- celldetective/gui/settings/_settings_tracking.py +1304 -1094
- celldetective/gui/settings/_stardist_model_params.py +98 -0
- celldetective/gui/survival_ui.py +422 -312
- celldetective/gui/tableUI.py +1665 -1701
- celldetective/gui/table_ops/_maths.py +295 -0
- celldetective/gui/table_ops/_merge_groups.py +140 -0
- celldetective/gui/table_ops/_merge_one_hot.py +95 -0
- celldetective/gui/table_ops/_query_table.py +43 -0
- celldetective/gui/table_ops/_rename_col.py +44 -0
- celldetective/gui/thresholds_gui.py +382 -179
- celldetective/gui/viewers/__init__.py +0 -0
- celldetective/gui/viewers/base_viewer.py +700 -0
- celldetective/gui/viewers/channel_offset_viewer.py +331 -0
- celldetective/gui/viewers/contour_viewer.py +394 -0
- celldetective/gui/viewers/size_viewer.py +153 -0
- celldetective/gui/viewers/spot_detection_viewer.py +341 -0
- celldetective/gui/viewers/threshold_viewer.py +309 -0
- celldetective/gui/workers.py +304 -126
- celldetective/log_manager.py +92 -0
- celldetective/measure.py +1895 -1478
- celldetective/napari/__init__.py +0 -0
- celldetective/napari/utils.py +1025 -0
- celldetective/neighborhood.py +1914 -1448
- celldetective/preprocessing.py +1620 -1220
- celldetective/processes/__init__.py +0 -0
- celldetective/processes/background_correction.py +271 -0
- celldetective/processes/compute_neighborhood.py +894 -0
- celldetective/processes/detect_events.py +246 -0
- celldetective/processes/measure_cells.py +565 -0
- celldetective/processes/segment_cells.py +760 -0
- celldetective/processes/track_cells.py +435 -0
- celldetective/processes/train_segmentation_model.py +694 -0
- celldetective/processes/train_signal_model.py +265 -0
- celldetective/processes/unified_process.py +292 -0
- celldetective/regionprops/_regionprops.py +358 -317
- celldetective/relative_measurements.py +987 -710
- celldetective/scripts/measure_cells.py +313 -212
- celldetective/scripts/measure_relative.py +90 -46
- celldetective/scripts/segment_cells.py +165 -104
- celldetective/scripts/segment_cells_thresholds.py +96 -68
- celldetective/scripts/track_cells.py +198 -149
- celldetective/scripts/train_segmentation_model.py +324 -201
- celldetective/scripts/train_signal_model.py +87 -45
- celldetective/segmentation.py +844 -749
- celldetective/signals.py +3514 -2861
- celldetective/tracking.py +30 -15
- celldetective/utils/__init__.py +0 -0
- celldetective/utils/cellpose_utils/__init__.py +133 -0
- celldetective/utils/color_mappings.py +42 -0
- celldetective/utils/data_cleaning.py +630 -0
- celldetective/utils/data_loaders.py +450 -0
- celldetective/utils/dataset_helpers.py +207 -0
- celldetective/utils/downloaders.py +197 -0
- celldetective/utils/event_detection/__init__.py +8 -0
- celldetective/utils/experiment.py +1782 -0
- celldetective/utils/image_augmenters.py +308 -0
- celldetective/utils/image_cleaning.py +74 -0
- celldetective/utils/image_loaders.py +926 -0
- celldetective/utils/image_transforms.py +335 -0
- celldetective/utils/io.py +62 -0
- celldetective/utils/mask_cleaning.py +348 -0
- celldetective/utils/mask_transforms.py +5 -0
- celldetective/utils/masks.py +184 -0
- celldetective/utils/maths.py +351 -0
- celldetective/utils/model_getters.py +325 -0
- celldetective/utils/model_loaders.py +296 -0
- celldetective/utils/normalization.py +380 -0
- celldetective/utils/parsing.py +465 -0
- celldetective/utils/plots/__init__.py +0 -0
- celldetective/utils/plots/regression.py +53 -0
- celldetective/utils/resources.py +34 -0
- celldetective/utils/stardist_utils/__init__.py +104 -0
- celldetective/utils/stats.py +90 -0
- celldetective/utils/types.py +21 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/METADATA +1 -1
- celldetective-1.5.0b0.dist-info/RECORD +187 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/WHEEL +1 -1
- tests/gui/test_new_project.py +129 -117
- tests/gui/test_project.py +127 -79
- tests/test_filters.py +39 -15
- tests/test_notebooks.py +8 -0
- tests/test_tracking.py +232 -13
- tests/test_utils.py +123 -77
- celldetective/gui/base_components.py +0 -23
- celldetective/gui/layouts.py +0 -1602
- celldetective/gui/processes/compute_neighborhood.py +0 -594
- celldetective/gui/processes/measure_cells.py +0 -360
- celldetective/gui/processes/segment_cells.py +0 -499
- celldetective/gui/processes/track_cells.py +0 -303
- celldetective/gui/processes/train_segmentation_model.py +0 -270
- celldetective/gui/processes/train_signal_model.py +0 -108
- celldetective/gui/table_ops/merge_groups.py +0 -118
- celldetective/gui/viewers.py +0 -1354
- celldetective/io.py +0 -3663
- celldetective/utils.py +0 -3108
- celldetective-1.4.2.dist-info/RECORD +0 -123
- /celldetective/{gui/processes → processes}/downloader.py +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/entry_points.txt +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/licenses/LICENSE +0 -0
- {celldetective-1.4.2.dist-info → celldetective-1.5.0b0.dist-info}/top_level.txt +0 -0
|
@@ -1,23 +1,41 @@
|
|
|
1
|
-
from PyQt5.QtWidgets import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
from PyQt5.QtWidgets import (
|
|
2
|
+
QMessageBox,
|
|
3
|
+
QScrollArea,
|
|
4
|
+
QButtonGroup,
|
|
5
|
+
QComboBox,
|
|
6
|
+
QCheckBox,
|
|
7
|
+
QVBoxLayout,
|
|
8
|
+
QLabel,
|
|
9
|
+
QHBoxLayout,
|
|
10
|
+
QPushButton,
|
|
11
|
+
QRadioButton,
|
|
12
|
+
QSizePolicy,
|
|
13
|
+
)
|
|
4
14
|
from PyQt5.QtCore import Qt, QRect
|
|
5
15
|
from PyQt5.QtGui import QDoubleValidator
|
|
6
16
|
|
|
7
|
-
from celldetective.gui import CelldetectiveWidget
|
|
8
|
-
from celldetective.gui.
|
|
17
|
+
from celldetective.gui.base.components import CelldetectiveWidget
|
|
18
|
+
from celldetective.gui.base.figure_canvas import FigureCanvas
|
|
19
|
+
from celldetective.gui.base.utils import center_window
|
|
9
20
|
|
|
10
21
|
from superqt.fonticon import icon
|
|
11
22
|
from fonticon_mdi6 import MDI6
|
|
12
|
-
from celldetective
|
|
13
|
-
from celldetective.
|
|
14
|
-
|
|
23
|
+
from celldetective import get_software_location
|
|
24
|
+
from celldetective.utils.parsing import _extract_labels_from_config
|
|
25
|
+
from celldetective.utils.data_loaders import load_experiment_tables
|
|
26
|
+
from celldetective.utils.experiment import (
|
|
27
|
+
get_experiment_wells,
|
|
28
|
+
get_experiment_concentrations,
|
|
29
|
+
get_experiment_cell_types,
|
|
30
|
+
get_experiment_antibodies,
|
|
31
|
+
get_positions_in_well,
|
|
32
|
+
)
|
|
15
33
|
import numpy as np
|
|
16
34
|
import json
|
|
17
35
|
import os
|
|
18
36
|
import matplotlib.pyplot as plt
|
|
19
37
|
|
|
20
|
-
plt.rcParams[
|
|
38
|
+
plt.rcParams["svg.fonttype"] = "none"
|
|
21
39
|
from glob import glob
|
|
22
40
|
import pandas as pd
|
|
23
41
|
from matplotlib.cm import tab10
|
|
@@ -52,15 +70,21 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
52
70
|
# sns.color_palette("cubehelix", as_cmap=True)
|
|
53
71
|
# sns.color_palette("ch:s=-.2,r=.6", as_cmap=True)
|
|
54
72
|
|
|
55
|
-
print(
|
|
73
|
+
print("Parent wells: ", self.wells)
|
|
56
74
|
|
|
57
|
-
self.well_option =
|
|
58
|
-
|
|
75
|
+
self.well_option = (
|
|
76
|
+
self.parent_window.parent_window.well_list.getSelectedIndices()
|
|
77
|
+
)
|
|
78
|
+
self.position_option = (
|
|
79
|
+
self.parent_window.parent_window.position_list.getSelectedIndices()
|
|
80
|
+
)
|
|
59
81
|
self.interpret_pos_location()
|
|
60
82
|
# self.load_available_tables()
|
|
61
83
|
# self.config_path = self.exp_dir + self.config_name
|
|
62
84
|
|
|
63
|
-
self.screen_height =
|
|
85
|
+
self.screen_height = (
|
|
86
|
+
self.parent_window.parent_window.parent_window.screen_height
|
|
87
|
+
)
|
|
64
88
|
center_window(self)
|
|
65
89
|
# self.setMinimumHeight(int(0.8*self.screen_height))
|
|
66
90
|
# self.setMaximumHeight(int(0.8*self.screen_height))
|
|
@@ -71,7 +95,6 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
71
95
|
self.hue_colors = {0: self.palette[0], 1: self.palette[3]}
|
|
72
96
|
|
|
73
97
|
def interpret_pos_location(self):
|
|
74
|
-
|
|
75
98
|
"""
|
|
76
99
|
Read the well/position selection from the control panel to decide which data to load
|
|
77
100
|
Set position_indices to None if all positions must be taken
|
|
@@ -89,7 +112,6 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
89
112
|
self.position_indices = np.array([self.position_option], dtype=int)
|
|
90
113
|
|
|
91
114
|
def populate_widget(self):
|
|
92
|
-
|
|
93
115
|
"""
|
|
94
116
|
Create the multibox design.
|
|
95
117
|
|
|
@@ -99,15 +121,25 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
99
121
|
main_layout = QVBoxLayout()
|
|
100
122
|
self.setLayout(main_layout)
|
|
101
123
|
main_layout.setContentsMargins(30, 30, 30, 30)
|
|
102
|
-
panel_title = QLabel(
|
|
103
|
-
panel_title.setStyleSheet(
|
|
124
|
+
panel_title = QLabel("Options")
|
|
125
|
+
panel_title.setStyleSheet(
|
|
126
|
+
"""
|
|
104
127
|
font-weight: bold;
|
|
105
128
|
padding: 0px;
|
|
106
|
-
"""
|
|
129
|
+
"""
|
|
130
|
+
)
|
|
107
131
|
main_layout.addWidget(panel_title, alignment=Qt.AlignCenter)
|
|
108
132
|
|
|
109
|
-
labels = [
|
|
110
|
-
|
|
133
|
+
labels = [
|
|
134
|
+
QLabel("population: "),
|
|
135
|
+
QLabel("class: "),
|
|
136
|
+
QLabel("group: "),
|
|
137
|
+
] # , QLabel('time of\ninterest: ')]
|
|
138
|
+
self.cb_options = [
|
|
139
|
+
self.parent_window.parent_window.populations,
|
|
140
|
+
["class"],
|
|
141
|
+
["group"],
|
|
142
|
+
] # , ['t0','first detection']]
|
|
111
143
|
self.cbs = [QComboBox() for i in range(len(labels))]
|
|
112
144
|
self.cbs[0].currentIndexChanged.connect(self.set_classes_and_times)
|
|
113
145
|
|
|
@@ -164,7 +196,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
164
196
|
# #time_calib_layout.addWidget(QLabel(' min'))
|
|
165
197
|
# main_layout.addLayout(time_calib_layout)
|
|
166
198
|
|
|
167
|
-
self.submit_btn = QPushButton(
|
|
199
|
+
self.submit_btn = QPushButton("Submit")
|
|
168
200
|
self.submit_btn.setStyleSheet(self.button_style_sheet)
|
|
169
201
|
self.submit_btn.clicked.connect(self.process_signal)
|
|
170
202
|
main_layout.addWidget(self.submit_btn)
|
|
@@ -189,31 +221,34 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
189
221
|
self.cbs[2].setEnabled(False)
|
|
190
222
|
|
|
191
223
|
def set_classes_and_times(self):
|
|
192
|
-
ext =
|
|
224
|
+
ext = "csv"
|
|
193
225
|
# Look for all classes and times
|
|
194
|
-
tables = glob(
|
|
226
|
+
tables = glob(
|
|
227
|
+
self.exp_dir
|
|
228
|
+
+ os.sep.join(["W*", "*", "output", "tables", f"trajectories_*{ext}"])
|
|
229
|
+
)
|
|
195
230
|
self.all_columns = []
|
|
196
231
|
for tab in tables:
|
|
197
232
|
cols = pd.read_csv(tab, nrows=1).columns.tolist()
|
|
198
233
|
self.all_columns.extend(cols)
|
|
199
234
|
self.all_columns = np.unique(self.all_columns)
|
|
200
|
-
class_idx = np.array([s.startswith(
|
|
201
|
-
group_idx = np.array([s.startswith(
|
|
235
|
+
class_idx = np.array([s.startswith("class_") for s in self.all_columns])
|
|
236
|
+
group_idx = np.array([s.startswith("group_") for s in self.all_columns])
|
|
202
237
|
|
|
203
|
-
print(f
|
|
238
|
+
print(f"{class_idx=} {group_idx=} {self.all_columns=}")
|
|
204
239
|
# time_idx = np.array([s.startswith('t_') for s in self.all_columns])
|
|
205
240
|
try:
|
|
206
|
-
if len(class_idx)>0:
|
|
241
|
+
if len(class_idx) > 0:
|
|
207
242
|
class_columns = list(self.all_columns[class_idx])
|
|
208
243
|
else:
|
|
209
244
|
class_columns = []
|
|
210
|
-
if len(group_idx)>0:
|
|
245
|
+
if len(group_idx) > 0:
|
|
211
246
|
group_columns = list(self.all_columns[group_idx])
|
|
212
247
|
else:
|
|
213
248
|
group_columns = []
|
|
214
249
|
# time_columns = list(self.all_columns[time_idx])
|
|
215
250
|
except Exception as e:
|
|
216
|
-
print(f
|
|
251
|
+
print(f"L210 columns not found {e}")
|
|
217
252
|
self.auto_close = True
|
|
218
253
|
return None
|
|
219
254
|
|
|
@@ -238,11 +273,11 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
238
273
|
self.feature_cb = QComboBox()
|
|
239
274
|
self.feature_cb.addItems(feats)
|
|
240
275
|
hbox = QHBoxLayout()
|
|
241
|
-
hbox.addWidget(QLabel(
|
|
276
|
+
hbox.addWidget(QLabel("feature: "), 33)
|
|
242
277
|
hbox.addWidget(self.feature_cb, 66)
|
|
243
278
|
layout.addLayout(hbox)
|
|
244
279
|
|
|
245
|
-
self.set_feature_btn = QPushButton(
|
|
280
|
+
self.set_feature_btn = QPushButton("set")
|
|
246
281
|
self.set_feature_btn.clicked.connect(self.compute_signals)
|
|
247
282
|
layout.addWidget(self.set_feature_btn)
|
|
248
283
|
self.feature_choice_widget.show()
|
|
@@ -261,7 +296,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
261
296
|
self.feature_cb = QComboBox()
|
|
262
297
|
self.feature_cb.addItems(feats)
|
|
263
298
|
hbox = QHBoxLayout()
|
|
264
|
-
hbox.addWidget(QLabel(
|
|
299
|
+
hbox.addWidget(QLabel("feature: "), 33)
|
|
265
300
|
hbox.addWidget(self.feature_cb, 66)
|
|
266
301
|
# hbox.addWidget((QLabel('Plot two features')))
|
|
267
302
|
layout.addLayout(hbox)
|
|
@@ -282,7 +317,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
282
317
|
# hbox_two.addWidget(self.feature_two_cb, 66)
|
|
283
318
|
# layout.addLayout(hbox_two)
|
|
284
319
|
|
|
285
|
-
self.set_feature_btn = QPushButton(
|
|
320
|
+
self.set_feature_btn = QPushButton("set")
|
|
286
321
|
self.set_feature_btn.clicked.connect(self.compute_signals)
|
|
287
322
|
layout.addWidget(self.set_feature_btn)
|
|
288
323
|
self.feature_choice_widget.show()
|
|
@@ -306,32 +341,34 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
306
341
|
self.survivalWidget = CelldetectiveWidget()
|
|
307
342
|
self.scroll = QScrollArea()
|
|
308
343
|
self.survivalWidget.setMinimumHeight(int(0.8 * self.screen_height))
|
|
309
|
-
self.survivalWidget.setWindowTitle(
|
|
344
|
+
self.survivalWidget.setWindowTitle("signals")
|
|
310
345
|
self.plotvbox = QVBoxLayout(self.survivalWidget)
|
|
311
346
|
self.plotvbox.setContentsMargins(30, 30, 30, 30)
|
|
312
|
-
self.survival_title = QLabel(
|
|
313
|
-
self.survival_title.setStyleSheet(
|
|
347
|
+
self.survival_title = QLabel("Signal function")
|
|
348
|
+
self.survival_title.setStyleSheet(
|
|
349
|
+
"""
|
|
314
350
|
font-weight: bold;
|
|
315
351
|
padding: 0px;
|
|
316
|
-
"""
|
|
352
|
+
"""
|
|
353
|
+
)
|
|
317
354
|
self.plotvbox.addWidget(self.survival_title, alignment=Qt.AlignCenter)
|
|
318
355
|
|
|
319
356
|
plot_buttons_hbox = QHBoxLayout()
|
|
320
|
-
plot_buttons_hbox.addWidget(QLabel(
|
|
357
|
+
plot_buttons_hbox.addWidget(QLabel(""), 80, alignment=Qt.AlignLeft)
|
|
321
358
|
|
|
322
|
-
self.legend_btn = QPushButton(
|
|
359
|
+
self.legend_btn = QPushButton("")
|
|
323
360
|
self.legend_btn.setIcon(icon(MDI6.text_box, color="black"))
|
|
324
361
|
self.legend_btn.setStyleSheet(self.button_select_all)
|
|
325
|
-
self.legend_btn.setToolTip(
|
|
362
|
+
self.legend_btn.setToolTip("Show or hide the legend")
|
|
326
363
|
self.legend_visible = True
|
|
327
364
|
self.legend_btn.clicked.connect(self.show_hide_legend)
|
|
328
365
|
plot_buttons_hbox.addWidget(self.legend_btn, 5, alignment=Qt.AlignRight)
|
|
329
366
|
|
|
330
|
-
self.log_btn = QPushButton(
|
|
367
|
+
self.log_btn = QPushButton("")
|
|
331
368
|
self.log_btn.setIcon(icon(MDI6.math_log, color="black"))
|
|
332
369
|
self.log_btn.setStyleSheet(self.button_select_all)
|
|
333
370
|
self.log_btn.clicked.connect(self.switch_to_log)
|
|
334
|
-
self.log_btn.setToolTip(
|
|
371
|
+
self.log_btn.setToolTip("Enable or disable log scale")
|
|
335
372
|
plot_buttons_hbox.addWidget(self.log_btn, 5, alignment=Qt.AlignRight)
|
|
336
373
|
|
|
337
374
|
# self.ci_btn = QPushButton('')
|
|
@@ -341,11 +378,11 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
341
378
|
# self.ci_btn.setToolTip('Show or hide confidence intervals.')
|
|
342
379
|
# plot_buttons_hbox.addWidget(self.ci_btn, 5, alignment=Qt.AlignRight)
|
|
343
380
|
|
|
344
|
-
self.cell_lines_btn = QPushButton(
|
|
381
|
+
self.cell_lines_btn = QPushButton("")
|
|
345
382
|
self.cell_lines_btn.setIcon(icon(MDI6.view_headline, color="black"))
|
|
346
383
|
self.cell_lines_btn.setStyleSheet(self.button_select_all)
|
|
347
384
|
self.cell_lines_btn.clicked.connect(self.switch_cell_lines)
|
|
348
|
-
self.cell_lines_btn.setToolTip(
|
|
385
|
+
self.cell_lines_btn.setToolTip("Show or hide individual cell signals.")
|
|
349
386
|
plot_buttons_hbox.addWidget(self.cell_lines_btn, 5, alignment=Qt.AlignRight)
|
|
350
387
|
|
|
351
388
|
self.fig, self.ax = plt.subplots(1, 1, figsize=(10, 10)) # ,figsize=(10,10)
|
|
@@ -356,22 +393,22 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
356
393
|
self.initialize_axis()
|
|
357
394
|
plt.tight_layout()
|
|
358
395
|
|
|
359
|
-
self.fig.set_facecolor(
|
|
396
|
+
self.fig.set_facecolor("none") # or 'None'
|
|
360
397
|
self.fig.canvas.setStyleSheet("background-color: transparent;")
|
|
361
398
|
self.survival_window.canvas.draw()
|
|
362
399
|
|
|
363
400
|
# self.survival_window.layout.addWidget(QLabel('WHAAAAATTT???'))
|
|
364
401
|
|
|
365
402
|
self.plot_options = [QRadioButton() for i in range(3)]
|
|
366
|
-
self.radio_labels = [
|
|
403
|
+
self.radio_labels = ["well", "pos", "both"]
|
|
367
404
|
radio_hbox = QHBoxLayout()
|
|
368
|
-
radio_hbox.setContentsMargins(30,30,30,30)
|
|
405
|
+
radio_hbox.setContentsMargins(30, 30, 30, 30)
|
|
369
406
|
self.plot_btn_group = QButtonGroup()
|
|
370
407
|
for i in range(3):
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
408
|
+
self.plot_options[i].setText(self.radio_labels[i])
|
|
409
|
+
# self.plot_options[i].toggled.connect(self.plot_survivals)
|
|
410
|
+
self.plot_btn_group.addButton(self.plot_options[i])
|
|
411
|
+
radio_hbox.addWidget(self.plot_options[i], 33, alignment=Qt.AlignCenter)
|
|
375
412
|
self.plot_btn_group.buttonClicked[int].connect(self.plot_survivals)
|
|
376
413
|
|
|
377
414
|
if self.position_indices is not None:
|
|
@@ -427,11 +464,13 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
427
464
|
# class_selection_hbox.addWidget(self.no_event_btn, 33, alignment=Qt.AlignRight)
|
|
428
465
|
# self.plotvbox.addLayout(class_selection_hbox)
|
|
429
466
|
|
|
430
|
-
self.select_pos_label = QLabel(
|
|
431
|
-
self.select_pos_label.setStyleSheet(
|
|
467
|
+
self.select_pos_label = QLabel("Select positions")
|
|
468
|
+
self.select_pos_label.setStyleSheet(
|
|
469
|
+
"""
|
|
432
470
|
font-weight: bold;
|
|
433
471
|
padding: 0px;
|
|
434
|
-
"""
|
|
472
|
+
"""
|
|
473
|
+
)
|
|
435
474
|
self.plotvbox.addWidget(self.select_pos_label, alignment=Qt.AlignCenter)
|
|
436
475
|
#
|
|
437
476
|
# self.select_option = [QRadioButton() for i in range(2)]
|
|
@@ -454,14 +493,14 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
454
493
|
self.load_coordinates()
|
|
455
494
|
self.plot_spatial_location()
|
|
456
495
|
# self.plot_positions()
|
|
457
|
-
self.ax_scatter.spines[
|
|
458
|
-
self.ax_scatter.spines[
|
|
459
|
-
self.ax_scatter.set_aspect(
|
|
496
|
+
self.ax_scatter.spines["top"].set_visible(False)
|
|
497
|
+
self.ax_scatter.spines["right"].set_visible(False)
|
|
498
|
+
self.ax_scatter.set_aspect("equal")
|
|
460
499
|
self.ax_scatter.set_xticks([])
|
|
461
500
|
self.ax_scatter.set_yticks([])
|
|
462
501
|
plt.tight_layout()
|
|
463
502
|
|
|
464
|
-
self.fig_scatter.set_facecolor(
|
|
503
|
+
self.fig_scatter.set_facecolor("none") # or 'None'
|
|
465
504
|
self.fig_scatter.canvas.setStyleSheet("background-color: transparent;")
|
|
466
505
|
self.plotvbox.addWidget(self.position_scatter)
|
|
467
506
|
|
|
@@ -476,14 +515,16 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
476
515
|
self.scroll.setWidget(self.survivalWidget)
|
|
477
516
|
|
|
478
517
|
self.scroll.setMinimumHeight(int(0.8 * self.screen_height))
|
|
479
|
-
self.survivalWidget.setSizePolicy(
|
|
518
|
+
self.survivalWidget.setSizePolicy(
|
|
519
|
+
QSizePolicy.Expanding, QSizePolicy.Expanding
|
|
520
|
+
)
|
|
480
521
|
self.scroll.show()
|
|
481
522
|
|
|
482
523
|
def process_signal(self):
|
|
483
524
|
|
|
484
|
-
print(
|
|
525
|
+
print("you clicked!!")
|
|
485
526
|
# self.FrameToMin = float(self.time_calibration_le.text().replace(',','.'))
|
|
486
|
-
print(self.FrameToMin,
|
|
527
|
+
print(self.FrameToMin, "set")
|
|
487
528
|
|
|
488
529
|
# read instructions from combobox options
|
|
489
530
|
self.load_available_tables()
|
|
@@ -494,51 +535,68 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
494
535
|
|
|
495
536
|
def generate_pos_selection_widget(self):
|
|
496
537
|
|
|
497
|
-
self.well_names = self.df[
|
|
538
|
+
self.well_names = self.df["well_name"].unique()
|
|
498
539
|
self.pos_names = self.df_pos_info[
|
|
499
|
-
|
|
500
|
-
|
|
540
|
+
"pos_name"
|
|
541
|
+
].unique() # pd.DataFrame(self.ks_estimators_per_position)['position_name'].unique()
|
|
542
|
+
print(f"POSITION NAMES: ", self.pos_names)
|
|
501
543
|
self.usable_well_labels = []
|
|
502
544
|
for name in self.well_names:
|
|
503
545
|
for lbl in self.well_labels:
|
|
504
|
-
if name +
|
|
546
|
+
if name + ":" in lbl:
|
|
505
547
|
self.usable_well_labels.append(lbl)
|
|
506
548
|
|
|
507
549
|
self.line_choice_widget = CelldetectiveWidget()
|
|
508
550
|
self.line_check_vbox = QVBoxLayout()
|
|
509
551
|
self.line_choice_widget.setLayout(self.line_check_vbox)
|
|
510
552
|
if len(self.well_indices) > 1:
|
|
511
|
-
self.well_display_options = [
|
|
512
|
-
|
|
553
|
+
self.well_display_options = [
|
|
554
|
+
QCheckBox(self.usable_well_labels[i])
|
|
555
|
+
for i in range(len(self.usable_well_labels))
|
|
556
|
+
]
|
|
513
557
|
for i in range(len(self.well_names)):
|
|
514
|
-
self.line_check_vbox.addWidget(
|
|
558
|
+
self.line_check_vbox.addWidget(
|
|
559
|
+
self.well_display_options[i], alignment=Qt.AlignLeft
|
|
560
|
+
)
|
|
515
561
|
self.well_display_options[i].setChecked(True)
|
|
516
562
|
self.well_display_options[i].toggled.connect(self.select_survival_lines)
|
|
517
563
|
else:
|
|
518
|
-
self.pos_display_options = [
|
|
564
|
+
self.pos_display_options = [
|
|
565
|
+
QCheckBox(self.pos_names[i]) for i in range(len(self.pos_names))
|
|
566
|
+
]
|
|
519
567
|
for i in range(len(self.pos_names)):
|
|
520
|
-
self.line_check_vbox.addWidget(
|
|
568
|
+
self.line_check_vbox.addWidget(
|
|
569
|
+
self.pos_display_options[i], alignment=Qt.AlignLeft
|
|
570
|
+
)
|
|
521
571
|
self.pos_display_options[i].setChecked(True)
|
|
522
572
|
self.pos_display_options[i].toggled.connect(self.select_survival_lines)
|
|
523
573
|
|
|
524
574
|
self.plotvbox.addWidget(self.line_choice_widget, alignment=Qt.AlignCenter)
|
|
525
575
|
|
|
526
576
|
def load_available_tables(self):
|
|
527
|
-
|
|
528
577
|
"""
|
|
529
578
|
Load the tables of the selected wells/positions from the control Panel for the population of interest
|
|
530
579
|
|
|
531
580
|
"""
|
|
532
581
|
|
|
533
|
-
self.well_option =
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
self.
|
|
537
|
-
|
|
582
|
+
self.well_option = (
|
|
583
|
+
self.parent_window.parent_window.well_list.getSelectedIndices()
|
|
584
|
+
)
|
|
585
|
+
self.position_option = (
|
|
586
|
+
self.parent_window.parent_window.position_list.getSelectedIndices()
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
self.df, self.df_pos_info = load_experiment_tables(
|
|
590
|
+
self.exp_dir,
|
|
591
|
+
well_option=self.well_option,
|
|
592
|
+
position_option=self.position_option,
|
|
593
|
+
population=self.cbs[0].currentText(),
|
|
594
|
+
return_pos_info=True,
|
|
595
|
+
)
|
|
538
596
|
|
|
539
597
|
if self.df is None:
|
|
540
598
|
|
|
541
|
-
print(
|
|
599
|
+
print("No table could be found...")
|
|
542
600
|
msgBox = QMessageBox()
|
|
543
601
|
msgBox.setIcon(QMessageBox.Warning)
|
|
544
602
|
msgBox.setText("No table could be found to compute survival...")
|
|
@@ -552,21 +610,25 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
552
610
|
self.close()
|
|
553
611
|
return None
|
|
554
612
|
else:
|
|
555
|
-
self.df_well_info = self.df_pos_info.loc[
|
|
556
|
-
|
|
613
|
+
self.df_well_info = self.df_pos_info.loc[
|
|
614
|
+
:, ["well_path", "well_index", "well_name", "well_number", "well_alias"]
|
|
615
|
+
].drop_duplicates()
|
|
557
616
|
|
|
558
617
|
def compute_signal_functions(self):
|
|
559
618
|
wells = get_experiment_wells(self.exp_dir)
|
|
560
619
|
antibodies = get_experiment_antibodies(self.exp_dir)
|
|
561
620
|
cell_types = get_experiment_cell_types(self.exp_dir)
|
|
562
621
|
concentrations = get_experiment_concentrations(self.exp_dir)
|
|
563
|
-
well_name = [
|
|
622
|
+
well_name = [
|
|
623
|
+
" ".join([s1, "+", s2, s3, "pM"])
|
|
624
|
+
for s1, s2, s3 in zip(cell_types, antibodies, concentrations)
|
|
625
|
+
]
|
|
564
626
|
|
|
565
627
|
data = []
|
|
566
628
|
full_data = []
|
|
567
629
|
print(self.well_option)
|
|
568
630
|
if self.well_option > 1:
|
|
569
|
-
self.plot_mode =
|
|
631
|
+
self.plot_mode = "wells"
|
|
570
632
|
for z, well in enumerate(wells): # loop over wells
|
|
571
633
|
# print(well)
|
|
572
634
|
if z not in self.well_indices:
|
|
@@ -576,80 +638,114 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
576
638
|
for ind, pos in enumerate(positions): # loop over positions
|
|
577
639
|
if self.position_indices is not None:
|
|
578
640
|
if ind + 1 in self.position_indices:
|
|
579
|
-
print(f
|
|
641
|
+
print(f"Processing position {pos}...")
|
|
580
642
|
tab_tc = pos + os.sep.join(
|
|
581
|
-
[
|
|
643
|
+
[
|
|
644
|
+
"output",
|
|
645
|
+
"tables",
|
|
646
|
+
f"trajectories_{self.cbs[0].currentText()}.csv",
|
|
647
|
+
]
|
|
648
|
+
)
|
|
582
649
|
if not os.path.exists(tab_tc):
|
|
583
650
|
return None
|
|
584
651
|
else:
|
|
585
652
|
data = pd.read_csv(tab_tc)
|
|
586
|
-
data[
|
|
653
|
+
data["well_name"] = well_name[z]
|
|
587
654
|
full_data.append(data)
|
|
588
655
|
|
|
589
656
|
else:
|
|
590
|
-
print(f
|
|
657
|
+
print(f"Processing position {pos}...")
|
|
591
658
|
tab_tc = pos + os.sep.join(
|
|
592
|
-
[
|
|
659
|
+
[
|
|
660
|
+
"output",
|
|
661
|
+
"tables",
|
|
662
|
+
f"trajectories_{self.cbs[0].currentText()}.csv",
|
|
663
|
+
]
|
|
664
|
+
)
|
|
593
665
|
if not os.path.exists(tab_tc):
|
|
594
666
|
return None
|
|
595
667
|
else:
|
|
596
668
|
data = pd.read_csv(tab_tc)
|
|
597
|
-
data[
|
|
669
|
+
data["well_name"] = well_name[z]
|
|
598
670
|
full_data.append(data)
|
|
599
671
|
else:
|
|
600
|
-
self.plot_mode =
|
|
672
|
+
self.plot_mode = "positions"
|
|
601
673
|
positions = get_positions_in_well(wells[self.well_indices[0]])
|
|
602
674
|
for ind, pos in enumerate(positions): # loop over positions
|
|
603
675
|
pos_name = pos.split(os.sep)[-2]
|
|
604
676
|
if self.position_indices is not None:
|
|
605
677
|
if ind + 1 in self.position_indices:
|
|
606
|
-
print(f
|
|
678
|
+
print(f"Processing position {pos}...")
|
|
607
679
|
tab_tc = pos + os.sep.join(
|
|
608
|
-
[
|
|
680
|
+
[
|
|
681
|
+
"output",
|
|
682
|
+
"tables",
|
|
683
|
+
f"trajectories_{self.cbs[0].currentText()}.csv",
|
|
684
|
+
]
|
|
685
|
+
)
|
|
609
686
|
if not os.path.exists(tab_tc):
|
|
610
687
|
return None
|
|
611
688
|
else:
|
|
612
689
|
data = pd.read_csv(tab_tc)
|
|
613
|
-
data[
|
|
690
|
+
data["position"] = pos_name
|
|
614
691
|
full_data.append(data)
|
|
615
692
|
else:
|
|
616
|
-
print(f
|
|
617
|
-
tab_tc = pos + os.sep.join(
|
|
693
|
+
print(f"Processing position {pos}...")
|
|
694
|
+
tab_tc = pos + os.sep.join(
|
|
695
|
+
[
|
|
696
|
+
"output",
|
|
697
|
+
"tables",
|
|
698
|
+
f"trajectories_{self.cbs[0].currentText()}.csv",
|
|
699
|
+
]
|
|
700
|
+
)
|
|
618
701
|
if not os.path.exists(tab_tc):
|
|
619
702
|
return None
|
|
620
703
|
else:
|
|
621
704
|
data = pd.read_csv(tab_tc)
|
|
622
|
-
data[
|
|
705
|
+
data["position"] = pos_name
|
|
623
706
|
full_data.append(data)
|
|
624
707
|
self.plot_data = pd.concat(full_data, ignore_index=True)
|
|
625
708
|
|
|
626
|
-
def generate_synchronized_matrix(
|
|
709
|
+
def generate_synchronized_matrix(
|
|
710
|
+
self, well_group, feature_selected, cclass, max_time
|
|
711
|
+
):
|
|
627
712
|
|
|
628
713
|
if isinstance(cclass, int):
|
|
629
714
|
cclass = [cclass]
|
|
630
715
|
|
|
631
|
-
n_cells = len(well_group.groupby([
|
|
716
|
+
n_cells = len(well_group.groupby(["position", "TRACK_ID"]))
|
|
632
717
|
depth = int(2 * max_time + 3)
|
|
633
718
|
matrix = np.zeros((n_cells, depth))
|
|
634
719
|
matrix[:, :] = np.nan
|
|
635
720
|
mapping = np.arange(-max_time - 1, max_time + 2)
|
|
636
721
|
cid = 0
|
|
637
|
-
for block, movie_group in well_group.groupby(
|
|
638
|
-
for tid, track_group in movie_group.loc[
|
|
639
|
-
|
|
722
|
+
for block, movie_group in well_group.groupby("position"):
|
|
723
|
+
for tid, track_group in movie_group.loc[
|
|
724
|
+
movie_group[self.cbs[1].currentText()].isin(cclass)
|
|
725
|
+
].groupby("TRACK_ID"):
|
|
640
726
|
try:
|
|
641
|
-
timeline = track_group[
|
|
727
|
+
timeline = track_group["FRAME"].to_numpy().astype(int)
|
|
642
728
|
feature = track_group[feature_selected].to_numpy()
|
|
643
729
|
if self.checkBox_feature.isChecked():
|
|
644
|
-
second_feature = track_group[
|
|
645
|
-
|
|
646
|
-
|
|
730
|
+
second_feature = track_group[
|
|
731
|
+
self.second_feature_selected
|
|
732
|
+
].to_numpy()
|
|
733
|
+
if (
|
|
734
|
+
self.cbs[2].currentText().startswith("t")
|
|
735
|
+
and not self.abs_time_checkbox.isChecked()
|
|
736
|
+
):
|
|
737
|
+
t0 = math.floor(
|
|
738
|
+
track_group[self.cbs[2].currentText()].to_numpy()[0]
|
|
739
|
+
)
|
|
647
740
|
timeline -= t0
|
|
648
|
-
elif
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
741
|
+
elif (
|
|
742
|
+
self.cbs[2].currentText() == "first detection"
|
|
743
|
+
and not self.abs_time_checkbox.isChecked()
|
|
744
|
+
):
|
|
745
|
+
|
|
746
|
+
if "area" in list(track_group.columns):
|
|
747
|
+
print("area in list")
|
|
748
|
+
feat = track_group["area"].values
|
|
653
749
|
else:
|
|
654
750
|
feat = feature
|
|
655
751
|
|
|
@@ -687,146 +783,318 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
687
783
|
return mean_line, std_line
|
|
688
784
|
|
|
689
785
|
def initialize_axis(self):
|
|
690
|
-
plt.rcParams[
|
|
786
|
+
plt.rcParams["svg.fonttype"] = "none"
|
|
691
787
|
plt.rcParams["font.family"] = "sans-serif"
|
|
692
788
|
SMALL_SIZE = 5
|
|
693
789
|
MEDIUM_SIZE = 6
|
|
694
790
|
BIGGER_SIZE = 7
|
|
695
791
|
|
|
696
|
-
plt.rc(
|
|
697
|
-
plt.rc(
|
|
698
|
-
plt.rc(
|
|
699
|
-
plt.rc(
|
|
700
|
-
plt.rc(
|
|
701
|
-
plt.rc(
|
|
702
|
-
plt.rc(
|
|
792
|
+
plt.rc("font", size=SMALL_SIZE) # controls default text sizes
|
|
793
|
+
plt.rc("axes", titlesize=SMALL_SIZE) # fontsize of the axes title
|
|
794
|
+
plt.rc("axes", labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
|
|
795
|
+
plt.rc("xtick", labelsize=SMALL_SIZE) # fontsize of the tick labels
|
|
796
|
+
plt.rc("ytick", labelsize=SMALL_SIZE) # fontsize of the tick labels
|
|
797
|
+
plt.rc("legend", fontsize=SMALL_SIZE) # legend fontsize
|
|
798
|
+
plt.rc("figure", titlesize=BIGGER_SIZE) # fontsize of the figure title
|
|
703
799
|
|
|
704
800
|
fig, ax = plt.subplots(1, 1, figsize=(10, 5))
|
|
705
801
|
if self.well_option > 1:
|
|
706
802
|
if self.check_class.isChecked():
|
|
707
|
-
sns.boxenplot(
|
|
708
|
-
|
|
709
|
-
|
|
803
|
+
sns.boxenplot(
|
|
804
|
+
ax=self.ax,
|
|
805
|
+
data=self.plot_data,
|
|
806
|
+
y=self.feature_selected,
|
|
807
|
+
x="well_name",
|
|
808
|
+
hue=self.cbs[1].currentText(),
|
|
809
|
+
dodge=True,
|
|
810
|
+
palette=self.palette,
|
|
811
|
+
)
|
|
710
812
|
if self.show_cell_lines:
|
|
711
|
-
sns.stripplot(
|
|
712
|
-
|
|
713
|
-
|
|
813
|
+
sns.stripplot(
|
|
814
|
+
ax=self.ax,
|
|
815
|
+
data=self.plot_data,
|
|
816
|
+
y=self.feature_selected,
|
|
817
|
+
x="well_name",
|
|
818
|
+
hue=self.cbs[1].currentText(),
|
|
819
|
+
dodge=True,
|
|
820
|
+
alpha=0.3,
|
|
821
|
+
linewidth=0.5,
|
|
822
|
+
size=3,
|
|
823
|
+
palette=self.palette,
|
|
824
|
+
)
|
|
714
825
|
elif self.check_group.isChecked():
|
|
715
|
-
sns.boxenplot(
|
|
716
|
-
|
|
717
|
-
|
|
826
|
+
sns.boxenplot(
|
|
827
|
+
ax=self.ax,
|
|
828
|
+
data=self.plot_data,
|
|
829
|
+
y=self.feature_selected,
|
|
830
|
+
x="well_name",
|
|
831
|
+
hue=self.cbs[2].currentText(),
|
|
832
|
+
dodge=True,
|
|
833
|
+
palette=self.hue_colors,
|
|
834
|
+
)
|
|
718
835
|
if self.show_cell_lines:
|
|
719
|
-
sns.stripplot(
|
|
720
|
-
|
|
721
|
-
|
|
836
|
+
sns.stripplot(
|
|
837
|
+
ax=self.ax,
|
|
838
|
+
data=self.plot_data,
|
|
839
|
+
y=self.feature_selected,
|
|
840
|
+
x="well_name",
|
|
841
|
+
hue=self.cbs[2].currentText(),
|
|
842
|
+
dodge=True,
|
|
843
|
+
alpha=0.3,
|
|
844
|
+
linewidth=0.5,
|
|
845
|
+
size=3,
|
|
846
|
+
palette=self.hue_colors,
|
|
847
|
+
)
|
|
722
848
|
else:
|
|
723
|
-
sns.boxenplot(
|
|
724
|
-
|
|
725
|
-
|
|
849
|
+
sns.boxenplot(
|
|
850
|
+
ax=self.ax,
|
|
851
|
+
data=self.plot_data,
|
|
852
|
+
y=self.feature_selected,
|
|
853
|
+
x="well_name",
|
|
854
|
+
color=self.palette[0],
|
|
855
|
+
dodge=True,
|
|
856
|
+
)
|
|
726
857
|
if self.show_cell_lines:
|
|
727
|
-
sns.stripplot(
|
|
728
|
-
|
|
729
|
-
|
|
858
|
+
sns.stripplot(
|
|
859
|
+
ax=self.ax,
|
|
860
|
+
data=self.plot_data,
|
|
861
|
+
y=self.feature_selected,
|
|
862
|
+
x="well_name",
|
|
863
|
+
color=self.palette[0],
|
|
864
|
+
dodge=True,
|
|
865
|
+
alpha=0.3,
|
|
866
|
+
linewidth=0.5,
|
|
867
|
+
size=3,
|
|
868
|
+
)
|
|
730
869
|
else:
|
|
731
870
|
if self.check_class.isChecked():
|
|
732
|
-
sns.boxenplot(
|
|
733
|
-
|
|
734
|
-
|
|
871
|
+
sns.boxenplot(
|
|
872
|
+
ax=self.ax,
|
|
873
|
+
data=self.plot_data,
|
|
874
|
+
y=self.feature_selected,
|
|
875
|
+
x="position",
|
|
876
|
+
hue=self.cbs[1].currentText(),
|
|
877
|
+
dodge=True,
|
|
878
|
+
palette=self.palette,
|
|
879
|
+
)
|
|
735
880
|
if self.show_cell_lines:
|
|
736
|
-
sns.stripplot(
|
|
737
|
-
|
|
738
|
-
|
|
881
|
+
sns.stripplot(
|
|
882
|
+
ax=self.ax,
|
|
883
|
+
data=self.plot_data,
|
|
884
|
+
y=self.feature_selected,
|
|
885
|
+
x="position",
|
|
886
|
+
hue=self.cbs[1].currentText(),
|
|
887
|
+
dodge=True,
|
|
888
|
+
alpha=0.3,
|
|
889
|
+
linewidth=0.5,
|
|
890
|
+
size=3,
|
|
891
|
+
palette=self.palette,
|
|
892
|
+
)
|
|
739
893
|
elif self.check_group.isChecked():
|
|
740
|
-
sns.boxenplot(
|
|
741
|
-
|
|
742
|
-
|
|
894
|
+
sns.boxenplot(
|
|
895
|
+
ax=self.ax,
|
|
896
|
+
data=self.plot_data,
|
|
897
|
+
y=self.feature_selected,
|
|
898
|
+
x="position",
|
|
899
|
+
hue=self.cbs[2].currentText(),
|
|
900
|
+
dodge=True,
|
|
901
|
+
palette=self.hue_colors,
|
|
902
|
+
)
|
|
743
903
|
if self.show_cell_lines:
|
|
744
|
-
sns.stripplot(
|
|
745
|
-
|
|
746
|
-
|
|
904
|
+
sns.stripplot(
|
|
905
|
+
ax=self.ax,
|
|
906
|
+
data=self.plot_data,
|
|
907
|
+
y=self.feature_selected,
|
|
908
|
+
x="position",
|
|
909
|
+
hue=self.cbs[2].currentText(),
|
|
910
|
+
dodge=True,
|
|
911
|
+
alpha=0.3,
|
|
912
|
+
linewidth=0.5,
|
|
913
|
+
size=3,
|
|
914
|
+
palette=self.hue_colors,
|
|
915
|
+
)
|
|
747
916
|
else:
|
|
748
|
-
sns.boxenplot(
|
|
749
|
-
|
|
750
|
-
|
|
917
|
+
sns.boxenplot(
|
|
918
|
+
ax=self.ax,
|
|
919
|
+
data=self.plot_data,
|
|
920
|
+
y=self.feature_selected,
|
|
921
|
+
x="position",
|
|
922
|
+
color=self.palette[0],
|
|
923
|
+
dodge=True,
|
|
924
|
+
)
|
|
751
925
|
if self.show_cell_lines:
|
|
752
|
-
sns.stripplot(
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
926
|
+
sns.stripplot(
|
|
927
|
+
ax=self.ax,
|
|
928
|
+
data=self.plot_data,
|
|
929
|
+
y=self.feature_selected,
|
|
930
|
+
x="position",
|
|
931
|
+
color=self.palette[0],
|
|
932
|
+
dodge=True,
|
|
933
|
+
alpha=0.3,
|
|
934
|
+
linewidth=0.5,
|
|
935
|
+
size=3,
|
|
936
|
+
)
|
|
937
|
+
self.ax.spines["top"].set_visible(False)
|
|
938
|
+
self.ax.spines["right"].set_visible(False)
|
|
757
939
|
self.ax.set_ylabel(self.feature_selected)
|
|
758
940
|
# ax.set_ylim(0.95,1.3)
|
|
759
941
|
plt.tight_layout()
|
|
760
942
|
|
|
761
943
|
def plot_survivals(self, id):
|
|
762
944
|
self.ax.clear()
|
|
763
|
-
plt.rcParams[
|
|
945
|
+
plt.rcParams["svg.fonttype"] = "none"
|
|
764
946
|
plt.rcParams["font.family"] = "sans-serif"
|
|
765
947
|
SMALL_SIZE = 5
|
|
766
948
|
MEDIUM_SIZE = 6
|
|
767
949
|
BIGGER_SIZE = 7
|
|
768
950
|
|
|
769
|
-
plt.rc(
|
|
770
|
-
plt.rc(
|
|
771
|
-
plt.rc(
|
|
772
|
-
plt.rc(
|
|
773
|
-
plt.rc(
|
|
774
|
-
plt.rc(
|
|
775
|
-
plt.rc(
|
|
951
|
+
plt.rc("font", size=SMALL_SIZE) # controls default text sizes
|
|
952
|
+
plt.rc("axes", titlesize=SMALL_SIZE) # fontsize of the axes title
|
|
953
|
+
plt.rc("axes", labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
|
|
954
|
+
plt.rc("xtick", labelsize=SMALL_SIZE) # fontsize of the tick labels
|
|
955
|
+
plt.rc("ytick", labelsize=SMALL_SIZE) # fontsize of the tick labels
|
|
956
|
+
plt.rc("legend", fontsize=SMALL_SIZE) # legend fontsize
|
|
957
|
+
plt.rc("figure", titlesize=BIGGER_SIZE) # fontsize of the figure title
|
|
776
958
|
|
|
777
959
|
fig, ax = plt.subplots(1, 1, figsize=(10, 5))
|
|
778
960
|
if self.well_option > 1:
|
|
779
961
|
if self.check_class.isChecked():
|
|
780
|
-
sns.boxenplot(
|
|
781
|
-
|
|
782
|
-
|
|
962
|
+
sns.boxenplot(
|
|
963
|
+
ax=self.ax,
|
|
964
|
+
data=self.plot_data,
|
|
965
|
+
y=self.feature_selected,
|
|
966
|
+
x="well_name",
|
|
967
|
+
hue=self.cbs[1].currentText(),
|
|
968
|
+
dodge=True,
|
|
969
|
+
palette=self.palette,
|
|
970
|
+
)
|
|
783
971
|
if self.show_cell_lines:
|
|
784
|
-
sns.stripplot(
|
|
785
|
-
|
|
786
|
-
|
|
972
|
+
sns.stripplot(
|
|
973
|
+
ax=self.ax,
|
|
974
|
+
data=self.plot_data,
|
|
975
|
+
y=self.feature_selected,
|
|
976
|
+
x="well_name",
|
|
977
|
+
hue=self.cbs[1].currentText(),
|
|
978
|
+
dodge=True,
|
|
979
|
+
alpha=0.3,
|
|
980
|
+
linewidth=0.5,
|
|
981
|
+
size=3,
|
|
982
|
+
palette=self.palette,
|
|
983
|
+
)
|
|
787
984
|
elif self.check_group.isChecked():
|
|
788
|
-
sns.boxenplot(
|
|
789
|
-
|
|
790
|
-
|
|
985
|
+
sns.boxenplot(
|
|
986
|
+
ax=self.ax,
|
|
987
|
+
data=self.plot_data,
|
|
988
|
+
y=self.feature_selected,
|
|
989
|
+
x="well_name",
|
|
990
|
+
hue=self.cbs[2].currentText(),
|
|
991
|
+
dodge=True,
|
|
992
|
+
palette=self.hue_colors,
|
|
993
|
+
)
|
|
791
994
|
if self.show_cell_lines:
|
|
792
|
-
sns.stripplot(
|
|
793
|
-
|
|
794
|
-
|
|
995
|
+
sns.stripplot(
|
|
996
|
+
ax=self.ax,
|
|
997
|
+
data=self.plot_data,
|
|
998
|
+
y=self.feature_selected,
|
|
999
|
+
x="well_name",
|
|
1000
|
+
hue=self.cbs[2].currentText(),
|
|
1001
|
+
dodge=True,
|
|
1002
|
+
alpha=0.3,
|
|
1003
|
+
linewidth=0.5,
|
|
1004
|
+
size=3,
|
|
1005
|
+
palette=self.hue_colors,
|
|
1006
|
+
)
|
|
795
1007
|
else:
|
|
796
|
-
sns.boxenplot(
|
|
797
|
-
|
|
798
|
-
|
|
1008
|
+
sns.boxenplot(
|
|
1009
|
+
ax=self.ax,
|
|
1010
|
+
data=self.plot_data,
|
|
1011
|
+
y=self.feature_selected,
|
|
1012
|
+
x="well_name",
|
|
1013
|
+
color=self.palette[0],
|
|
1014
|
+
dodge=True,
|
|
1015
|
+
)
|
|
799
1016
|
if self.show_cell_lines:
|
|
800
|
-
sns.stripplot(
|
|
801
|
-
|
|
802
|
-
|
|
1017
|
+
sns.stripplot(
|
|
1018
|
+
ax=self.ax,
|
|
1019
|
+
data=self.plot_data,
|
|
1020
|
+
y=self.feature_selected,
|
|
1021
|
+
x="well_name",
|
|
1022
|
+
color=self.palette[0],
|
|
1023
|
+
dodge=True,
|
|
1024
|
+
alpha=0.3,
|
|
1025
|
+
linewidth=0.5,
|
|
1026
|
+
size=3,
|
|
1027
|
+
)
|
|
803
1028
|
else:
|
|
804
1029
|
if self.check_class.isChecked():
|
|
805
|
-
sns.boxenplot(
|
|
806
|
-
|
|
807
|
-
|
|
1030
|
+
sns.boxenplot(
|
|
1031
|
+
ax=self.ax,
|
|
1032
|
+
data=self.plot_data,
|
|
1033
|
+
y=self.feature_selected,
|
|
1034
|
+
x="position",
|
|
1035
|
+
hue=self.cbs[1].currentText(),
|
|
1036
|
+
dodge=True,
|
|
1037
|
+
palette=self.palette,
|
|
1038
|
+
)
|
|
808
1039
|
if self.show_cell_lines:
|
|
809
|
-
sns.stripplot(
|
|
810
|
-
|
|
811
|
-
|
|
1040
|
+
sns.stripplot(
|
|
1041
|
+
ax=self.ax,
|
|
1042
|
+
data=self.plot_data,
|
|
1043
|
+
y=self.feature_selected,
|
|
1044
|
+
x="position",
|
|
1045
|
+
hue=self.cbs[1].currentText(),
|
|
1046
|
+
dodge=True,
|
|
1047
|
+
alpha=0.3,
|
|
1048
|
+
linewidth=0.5,
|
|
1049
|
+
size=3,
|
|
1050
|
+
palette=self.palette,
|
|
1051
|
+
)
|
|
812
1052
|
elif self.check_group.isChecked():
|
|
813
|
-
sns.boxenplot(
|
|
814
|
-
|
|
815
|
-
|
|
1053
|
+
sns.boxenplot(
|
|
1054
|
+
ax=self.ax,
|
|
1055
|
+
data=self.plot_data,
|
|
1056
|
+
y=self.feature_selected,
|
|
1057
|
+
x="position",
|
|
1058
|
+
hue=self.cbs[2].currentText(),
|
|
1059
|
+
dodge=True,
|
|
1060
|
+
palette=self.hue_colors,
|
|
1061
|
+
)
|
|
816
1062
|
if self.show_cell_lines:
|
|
817
|
-
sns.stripplot(
|
|
818
|
-
|
|
819
|
-
|
|
1063
|
+
sns.stripplot(
|
|
1064
|
+
ax=self.ax,
|
|
1065
|
+
data=self.plot_data,
|
|
1066
|
+
y=self.feature_selected,
|
|
1067
|
+
x="position",
|
|
1068
|
+
hue=self.cbs[2].currentText(),
|
|
1069
|
+
dodge=True,
|
|
1070
|
+
alpha=0.3,
|
|
1071
|
+
linewidth=0.5,
|
|
1072
|
+
size=3,
|
|
1073
|
+
palette=self.hue_colors,
|
|
1074
|
+
)
|
|
820
1075
|
else:
|
|
821
|
-
sns.boxenplot(
|
|
822
|
-
|
|
823
|
-
|
|
1076
|
+
sns.boxenplot(
|
|
1077
|
+
ax=self.ax,
|
|
1078
|
+
data=self.plot_data,
|
|
1079
|
+
y=self.feature_selected,
|
|
1080
|
+
x="position",
|
|
1081
|
+
color=self.palette[0],
|
|
1082
|
+
dodge=True,
|
|
1083
|
+
)
|
|
824
1084
|
if self.show_cell_lines:
|
|
825
|
-
sns.stripplot(
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
1085
|
+
sns.stripplot(
|
|
1086
|
+
ax=self.ax,
|
|
1087
|
+
data=self.plot_data,
|
|
1088
|
+
y=self.feature_selected,
|
|
1089
|
+
x="position",
|
|
1090
|
+
color=self.palette[0],
|
|
1091
|
+
dodge=True,
|
|
1092
|
+
alpha=0.3,
|
|
1093
|
+
linewidth=0.5,
|
|
1094
|
+
size=3,
|
|
1095
|
+
)
|
|
1096
|
+
ax.spines["top"].set_visible(False)
|
|
1097
|
+
ax.spines["right"].set_visible(False)
|
|
830
1098
|
ax.set_ylabel(self.feature_selected)
|
|
831
1099
|
plt.tight_layout()
|
|
832
1100
|
self.survival_window.setMinimumHeight(int(0.5 * self.screen_height))
|
|
@@ -835,53 +1103,84 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
835
1103
|
|
|
836
1104
|
self.survival_window.canvas.draw()
|
|
837
1105
|
|
|
838
|
-
def plot_line(
|
|
839
|
-
|
|
1106
|
+
def plot_line(
|
|
1107
|
+
self,
|
|
1108
|
+
line,
|
|
1109
|
+
color,
|
|
1110
|
+
label,
|
|
1111
|
+
mean_signal,
|
|
1112
|
+
ci_option=True,
|
|
1113
|
+
cell_lines_option=False,
|
|
1114
|
+
alpha_ci=0.5,
|
|
1115
|
+
alpha_cell_lines=0.5,
|
|
1116
|
+
std_signal=None,
|
|
1117
|
+
matrix=None,
|
|
1118
|
+
):
|
|
840
1119
|
try:
|
|
841
|
-
if
|
|
842
|
-
self.ax2.plot(
|
|
1120
|
+
if "second" in str(mean_signal):
|
|
1121
|
+
self.ax2.plot(
|
|
1122
|
+
line["timeline"] * self.FrameToMin,
|
|
1123
|
+
line[mean_signal],
|
|
1124
|
+
color=color,
|
|
1125
|
+
label=label,
|
|
1126
|
+
)
|
|
843
1127
|
else:
|
|
844
|
-
self.ax.plot(
|
|
1128
|
+
self.ax.plot(
|
|
1129
|
+
line["timeline"] * self.FrameToMin,
|
|
1130
|
+
line[mean_signal],
|
|
1131
|
+
color=color,
|
|
1132
|
+
label=label,
|
|
1133
|
+
)
|
|
845
1134
|
if ci_option and std_signal is not None:
|
|
846
|
-
if
|
|
847
|
-
self.ax2.fill_between(
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1135
|
+
if "second" in str(mean_signal):
|
|
1136
|
+
self.ax2.fill_between(
|
|
1137
|
+
line["timeline"] * self.FrameToMin,
|
|
1138
|
+
[a - b for a, b in zip(line[mean_signal], line[std_signal])],
|
|
1139
|
+
[a + b for a, b in zip(line[mean_signal], line[std_signal])],
|
|
1140
|
+
color=color,
|
|
1141
|
+
alpha=alpha_ci,
|
|
1142
|
+
)
|
|
853
1143
|
else:
|
|
854
|
-
self.ax.fill_between(
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1144
|
+
self.ax.fill_between(
|
|
1145
|
+
line["timeline"] * self.FrameToMin,
|
|
1146
|
+
[a - b for a, b in zip(line[mean_signal], line[std_signal])],
|
|
1147
|
+
[a + b for a, b in zip(line[mean_signal], line[std_signal])],
|
|
1148
|
+
color=color,
|
|
1149
|
+
alpha=alpha_ci,
|
|
1150
|
+
)
|
|
860
1151
|
if cell_lines_option and matrix is not None:
|
|
861
1152
|
print(mean_signal)
|
|
862
1153
|
mat = line[matrix]
|
|
863
|
-
if
|
|
1154
|
+
if "second" in str(mean_signal):
|
|
864
1155
|
for i in range(mat.shape[0]):
|
|
865
|
-
self.ax2.plot(
|
|
866
|
-
|
|
1156
|
+
self.ax2.plot(
|
|
1157
|
+
line["timeline"] * self.FrameToMin,
|
|
1158
|
+
mat[i, :],
|
|
1159
|
+
color=color,
|
|
1160
|
+
alpha=alpha_cell_lines,
|
|
1161
|
+
)
|
|
867
1162
|
else:
|
|
868
1163
|
for i in range(mat.shape[0]):
|
|
869
|
-
self.ax.plot(
|
|
1164
|
+
self.ax.plot(
|
|
1165
|
+
line["timeline"] * self.FrameToMin,
|
|
1166
|
+
mat[i, :],
|
|
1167
|
+
color=color,
|
|
1168
|
+
alpha=alpha_cell_lines,
|
|
1169
|
+
)
|
|
870
1170
|
|
|
871
1171
|
except Exception as e:
|
|
872
|
-
print(f
|
|
1172
|
+
print(f"Exception {e}")
|
|
873
1173
|
|
|
874
1174
|
def switch_to_log(self):
|
|
875
|
-
|
|
876
1175
|
"""
|
|
877
1176
|
Switch threshold histogram to log scale. Auto adjust.
|
|
878
1177
|
"""
|
|
879
1178
|
|
|
880
|
-
if self.ax.get_yscale() ==
|
|
881
|
-
self.ax.set_yscale(
|
|
1179
|
+
if self.ax.get_yscale() == "linear":
|
|
1180
|
+
self.ax.set_yscale("log")
|
|
882
1181
|
# self.ax.set_ylim(0.01,1.05)
|
|
883
1182
|
else:
|
|
884
|
-
self.ax.set_yscale(
|
|
1183
|
+
self.ax.set_yscale("linear")
|
|
885
1184
|
# self.ax.set_ylim(0.01,1.05)
|
|
886
1185
|
|
|
887
1186
|
# self.ax.autoscale()
|
|
@@ -902,20 +1201,22 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
902
1201
|
def look_for_metadata(self):
|
|
903
1202
|
|
|
904
1203
|
self.metadata_found = False
|
|
905
|
-
self.metafiles =
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1204
|
+
self.metafiles = (
|
|
1205
|
+
glob(self.exp_dir + os.sep.join([f"W*", "*", "movie", "*metadata.txt"]))
|
|
1206
|
+
+ glob(self.exp_dir + os.sep.join([f"W*", "*", "*metadata.txt"]))
|
|
1207
|
+
+ glob(self.exp_dir + os.sep.join([f"W*", "*metadata.txt"]))
|
|
1208
|
+
+ glob(self.exp_dir + "*metadata.txt")
|
|
1209
|
+
)
|
|
1210
|
+
print(f"Found {len(self.metafiles)} metadata files...")
|
|
910
1211
|
if len(self.metafiles) > 0:
|
|
911
1212
|
self.metadata_found = True
|
|
912
1213
|
|
|
913
1214
|
def switch_selection_mode(self, id):
|
|
914
|
-
print(f
|
|
1215
|
+
print(f"button {id} was clicked")
|
|
915
1216
|
for i in range(2):
|
|
916
1217
|
if self.select_option[i].isChecked():
|
|
917
1218
|
self.selection_mode = self.select_label[i]
|
|
918
|
-
if self.selection_mode ==
|
|
1219
|
+
if self.selection_mode == "name":
|
|
919
1220
|
if len(self.metafiles) > 0:
|
|
920
1221
|
self.position_scatter.hide()
|
|
921
1222
|
self.line_choice_widget.show()
|
|
@@ -925,36 +1226,35 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
925
1226
|
self.line_choice_widget.hide()
|
|
926
1227
|
|
|
927
1228
|
def load_coordinates(self):
|
|
928
|
-
|
|
929
1229
|
"""
|
|
930
1230
|
Read metadata and try to extract position coordinates
|
|
931
1231
|
"""
|
|
932
1232
|
|
|
933
1233
|
self.no_meta = False
|
|
934
1234
|
try:
|
|
935
|
-
with open(self.metafiles[0],
|
|
1235
|
+
with open(self.metafiles[0], "r") as f:
|
|
936
1236
|
data = json.load(f)
|
|
937
|
-
positions = data[
|
|
1237
|
+
positions = data["Summary"]["InitialPositionList"]
|
|
938
1238
|
except Exception as e:
|
|
939
|
-
print(f
|
|
1239
|
+
print(f"Trouble loading metadata: error {e}...")
|
|
940
1240
|
return None
|
|
941
1241
|
|
|
942
1242
|
for k in range(len(positions)):
|
|
943
|
-
pos_label = positions[k][
|
|
1243
|
+
pos_label = positions[k]["Label"]
|
|
944
1244
|
try:
|
|
945
|
-
coords = positions[k][
|
|
1245
|
+
coords = positions[k]["DeviceCoordinatesUm"]["XYStage"]
|
|
946
1246
|
except:
|
|
947
1247
|
try:
|
|
948
|
-
coords = positions[k][
|
|
1248
|
+
coords = positions[k]["DeviceCoordinatesUm"]["PIXYStage"]
|
|
949
1249
|
except:
|
|
950
1250
|
self.no_meta = True
|
|
951
1251
|
|
|
952
1252
|
if not self.no_meta:
|
|
953
|
-
files = self.df_pos_info[
|
|
1253
|
+
files = self.df_pos_info["stack_path"].values
|
|
954
1254
|
pos_loc = [pos_label in f for f in files]
|
|
955
|
-
self.df_pos_info.loc[pos_loc,
|
|
956
|
-
self.df_pos_info.loc[pos_loc,
|
|
957
|
-
self.df_pos_info.loc[pos_loc,
|
|
1255
|
+
self.df_pos_info.loc[pos_loc, "x"] = coords[0]
|
|
1256
|
+
self.df_pos_info.loc[pos_loc, "y"] = coords[1]
|
|
1257
|
+
self.df_pos_info.loc[pos_loc, "metadata_tag"] = pos_label
|
|
958
1258
|
|
|
959
1259
|
def update_annot(self, ind):
|
|
960
1260
|
|
|
@@ -962,7 +1262,7 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
962
1262
|
self.annot.xy = pos
|
|
963
1263
|
text = self.scat_labels[ind["ind"][0]]
|
|
964
1264
|
self.annot.set_text(text)
|
|
965
|
-
self.annot.get_bbox_patch().set_facecolor(
|
|
1265
|
+
self.annot.get_bbox_patch().set_facecolor("k")
|
|
966
1266
|
self.annot.get_bbox_patch().set_alpha(0.4)
|
|
967
1267
|
|
|
968
1268
|
def hover(self, event):
|
|
@@ -979,22 +1279,28 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
979
1279
|
self.fig_scatter.canvas.draw_idle()
|
|
980
1280
|
|
|
981
1281
|
def unselect_position(self, event):
|
|
982
|
-
print(
|
|
1282
|
+
print("unselecting position")
|
|
983
1283
|
self.survival_window.canvas.clear()
|
|
984
1284
|
ind = event.ind # index of selected position
|
|
985
|
-
well_idx = self.df_pos_info.iloc[ind][
|
|
986
|
-
selectedPos = self.df_pos_info.iloc[ind][
|
|
987
|
-
currentSelState = self.df_pos_info.iloc[ind][
|
|
1285
|
+
well_idx = self.df_pos_info.iloc[ind]["well_index"].values[0]
|
|
1286
|
+
selectedPos = self.df_pos_info.iloc[ind]["pos_path"].values[0]
|
|
1287
|
+
currentSelState = self.df_pos_info.iloc[ind]["select"].values[0]
|
|
988
1288
|
if self.plot_options[0].isChecked() or self.plot_options[2].isChecked():
|
|
989
|
-
self.df_pos_info.loc[
|
|
990
|
-
|
|
1289
|
+
self.df_pos_info.loc[
|
|
1290
|
+
self.df_pos_info["well_index"] == well_idx, "select"
|
|
1291
|
+
] = not currentSelState
|
|
1292
|
+
self.df_well_info.loc[
|
|
1293
|
+
self.df_well_info["well_index"] == well_idx, "select"
|
|
1294
|
+
] = not currentSelState
|
|
991
1295
|
if len(self.well_indices) > 1:
|
|
992
1296
|
self.well_display_options[well_idx].setChecked(not currentSelState)
|
|
993
1297
|
else:
|
|
994
1298
|
for p in self.pos_display_options:
|
|
995
1299
|
p.setChecked(not currentSelState)
|
|
996
1300
|
else:
|
|
997
|
-
self.df_pos_info.loc[
|
|
1301
|
+
self.df_pos_info.loc[
|
|
1302
|
+
self.df_pos_info["pos_path"] == selectedPos, "select"
|
|
1303
|
+
] = not currentSelState
|
|
998
1304
|
if len(self.well_indices) <= 1:
|
|
999
1305
|
self.pos_display_options[ind[0]].setChecked(not currentSelState)
|
|
1000
1306
|
|
|
@@ -1003,17 +1309,19 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
1003
1309
|
self.plot_survivals(0)
|
|
1004
1310
|
|
|
1005
1311
|
def select_survival_lines(self):
|
|
1006
|
-
if self.plot_mode ==
|
|
1312
|
+
if self.plot_mode == "wells":
|
|
1007
1313
|
selected_wells = []
|
|
1008
1314
|
for i in range(len(self.well_display_options)):
|
|
1009
1315
|
if self.well_display_options[i].isChecked():
|
|
1010
1316
|
selected_wells.append(i)
|
|
1011
|
-
self.df_well_info.loc[
|
|
1012
|
-
i
|
|
1013
|
-
|
|
1014
|
-
|
|
1317
|
+
self.df_well_info.loc[
|
|
1318
|
+
self.df_well_info["well_index"] == i, "select"
|
|
1319
|
+
] = self.well_display_options[i].isChecked()
|
|
1320
|
+
self.df_pos_info.loc[self.df_pos_info["well_index"] == i, "select"] = (
|
|
1321
|
+
self.well_display_options[i].isChecked()
|
|
1322
|
+
)
|
|
1015
1323
|
if len(selected_wells) == 0:
|
|
1016
|
-
print(
|
|
1324
|
+
print("No wells selected")
|
|
1017
1325
|
self.ax.clear()
|
|
1018
1326
|
else:
|
|
1019
1327
|
self.ax.clear()
|
|
@@ -1025,8 +1333,9 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
1025
1333
|
for i in range(len(self.pos_display_options)):
|
|
1026
1334
|
if self.pos_display_options[i].isChecked():
|
|
1027
1335
|
selected_pos.append(i + 1)
|
|
1028
|
-
self.df_pos_info.loc[self.df_pos_info[
|
|
1029
|
-
i].isChecked()
|
|
1336
|
+
self.df_pos_info.loc[self.df_pos_info["pos_index"] == i, "select"] = (
|
|
1337
|
+
self.pos_display_options[i].isChecked()
|
|
1338
|
+
)
|
|
1030
1339
|
if len(selected_pos) == 0:
|
|
1031
1340
|
self.ax.clear()
|
|
1032
1341
|
else:
|
|
@@ -1046,13 +1355,23 @@ class ConfigMeasurementsPlot(CelldetectiveWidget):
|
|
|
1046
1355
|
def plot_spatial_location(self):
|
|
1047
1356
|
|
|
1048
1357
|
try:
|
|
1049
|
-
self.sc = self.ax_scatter.scatter(
|
|
1050
|
-
|
|
1051
|
-
|
|
1358
|
+
self.sc = self.ax_scatter.scatter(
|
|
1359
|
+
self.df_pos_info["x"].values,
|
|
1360
|
+
self.df_pos_info["y"].values,
|
|
1361
|
+
picker=True,
|
|
1362
|
+
pickradius=1,
|
|
1363
|
+
color=self.select_color(self.df_pos_info["select"].values),
|
|
1364
|
+
)
|
|
1365
|
+
self.scat_labels = self.df_pos_info["metadata_tag"].values
|
|
1052
1366
|
self.ax_scatter.invert_xaxis()
|
|
1053
|
-
self.annot = self.ax_scatter.annotate(
|
|
1054
|
-
|
|
1055
|
-
|
|
1367
|
+
self.annot = self.ax_scatter.annotate(
|
|
1368
|
+
"",
|
|
1369
|
+
xy=(0, 0),
|
|
1370
|
+
xytext=(10, 10),
|
|
1371
|
+
textcoords="offset points",
|
|
1372
|
+
bbox=dict(boxstyle="round", fc="w"),
|
|
1373
|
+
arrowprops=dict(arrowstyle="->"),
|
|
1374
|
+
)
|
|
1056
1375
|
self.annot.set_visible(False)
|
|
1057
1376
|
self.fig_scatter.canvas.mpl_connect("motion_notify_event", self.hover)
|
|
1058
1377
|
self.fig_scatter.canvas.mpl_connect("pick_event", self.unselect_position)
|