celldetective 1.3.4.post1__py3-none-any.whl → 1.3.6.post1__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/_version.py +1 -1
- celldetective/events.py +10 -5
- celldetective/filters.py +11 -0
- celldetective/gui/btrack_options.py +151 -1
- celldetective/gui/classifier_widget.py +44 -15
- celldetective/gui/configure_new_exp.py +13 -0
- celldetective/gui/control_panel.py +4 -2
- celldetective/gui/generic_signal_plot.py +2 -6
- celldetective/gui/gui_utils.py +170 -12
- celldetective/gui/measurement_options.py +85 -54
- celldetective/gui/neighborhood_options.py +1 -1
- celldetective/gui/plot_signals_ui.py +3 -4
- celldetective/gui/process_block.py +8 -6
- celldetective/gui/signal_annotator.py +10 -3
- celldetective/gui/signal_annotator2.py +146 -193
- celldetective/gui/survival_ui.py +121 -34
- celldetective/gui/tableUI.py +26 -12
- celldetective/gui/thresholds_gui.py +9 -52
- celldetective/gui/viewers.py +58 -21
- celldetective/io.py +1087 -161
- celldetective/measure.py +175 -102
- celldetective/preprocessing.py +2 -2
- celldetective/relative_measurements.py +6 -9
- celldetective/scripts/measure_cells.py +13 -3
- celldetective/scripts/segment_cells.py +0 -1
- celldetective/scripts/track_cells.py +25 -1
- celldetective/signals.py +9 -7
- celldetective/tracking.py +130 -81
- celldetective/utils.py +28 -7
- {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/METADATA +3 -2
- {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/RECORD +35 -35
- {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/LICENSE +0 -0
- {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/WHEEL +0 -0
- {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/entry_points.txt +0 -0
- {celldetective-1.3.4.post1.dist-info → celldetective-1.3.6.post1.dist-info}/top_level.txt +0 -0
|
@@ -7,7 +7,7 @@ from celldetective.gui import Styles
|
|
|
7
7
|
from celldetective.gui.gui_utils import center_window
|
|
8
8
|
from superqt import QLabeledDoubleRangeSlider, QSearchableComboBox
|
|
9
9
|
from celldetective.utils import extract_experiment_channels, get_software_location, _get_img_num_per_channel
|
|
10
|
-
from celldetective.io import auto_load_number_of_frames, load_frames
|
|
10
|
+
from celldetective.io import auto_load_number_of_frames, load_frames, get_experiment_metadata
|
|
11
11
|
from celldetective.gui.gui_utils import FigureCanvas, color_from_status, color_from_class
|
|
12
12
|
import json
|
|
13
13
|
import numpy as np
|
|
@@ -66,7 +66,10 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
66
66
|
't0', 'POSITION_X', 'POSITION_Y', 'position', 'well', 'well_index', 'well_name', 'pos_name',
|
|
67
67
|
'index', 'relxy', 'tc', 'nk', 'concentration', 'antibody', 'cell_type', 'pharmaceutical_agent',
|
|
68
68
|
'reference_population', 'neighbor_population']
|
|
69
|
-
|
|
69
|
+
meta = get_experiment_metadata(self.exp_dir)
|
|
70
|
+
if meta is not None:
|
|
71
|
+
keys = list(meta.keys())
|
|
72
|
+
self.cols_to_remove.extend(keys)
|
|
70
73
|
|
|
71
74
|
# Read instructions from target block for now...
|
|
72
75
|
self.mode = "neighborhood"
|
|
@@ -429,27 +432,12 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
429
432
|
contrast_hbox.addWidget(self.contrast_slider,90)
|
|
430
433
|
self.right_panel.addLayout(contrast_hbox, 5)
|
|
431
434
|
|
|
432
|
-
# speed_hbox = QHBoxLayout()
|
|
433
|
-
# speed_hbox.setContentsMargins(150,5,150,5)
|
|
434
|
-
# self.interval_slider = QLabeledSlider()
|
|
435
|
-
# self.interval_slider.setSingleStep(1)
|
|
436
|
-
# self.interval_slider.setTickInterval(1)
|
|
437
|
-
# self.interval_slider.setOrientation(1)
|
|
438
|
-
# self.interval_slider.setRange(1, 10000)
|
|
439
|
-
# self.interval_slider.setValue(self.speed)
|
|
440
|
-
# self.interval_slider.valueChanged.connect(self.interval_slider_action)
|
|
441
|
-
# speed_hbox.addWidget(QLabel('interval (ms): '))
|
|
442
|
-
# speed_hbox.addWidget(self.interval_slider,90)
|
|
443
|
-
# self.right_panel.addLayout(speed_hbox, 10)
|
|
444
|
-
|
|
445
|
-
#self.selected_populationulate_left_panel()
|
|
446
|
-
#grid.addLayout(self.left_side, 0, 0, 1, 1)
|
|
447
|
-
|
|
448
435
|
main_layout.addLayout(self.left_panel, 35)
|
|
449
436
|
main_layout.addLayout(self.right_panel, 65)
|
|
450
437
|
self.button_widget.adjustSize()
|
|
451
438
|
self.compute_status_and_colors_reference()
|
|
452
439
|
|
|
440
|
+
self.extract_relevant_events()
|
|
453
441
|
|
|
454
442
|
self.setCentralWidget(self.button_widget)
|
|
455
443
|
self.show()
|
|
@@ -673,23 +661,11 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
673
661
|
self.df_relative.loc[(~self.df_relative['status_'+self.current_neighborhood].isnull())&(self.df_relative['reference_population']==self.reference_population),self.relative_time] = 0.1
|
|
674
662
|
else:
|
|
675
663
|
self.df_relative.loc[(~self.df_relative['status_'+self.current_neighborhood].isnull())&(self.df_relative['reference_population']==self.reference_population),self.relative_time] = -1
|
|
676
|
-
|
|
677
|
-
self.relative_class_choice_cb.clear()
|
|
678
|
-
cols = np.array(self.df_relative.columns)
|
|
679
|
-
self.relative_class_cols = np.array([c.startswith('class') for c in list(self.df_relative.columns)])
|
|
680
|
-
self.relative_class_cols = list(cols[self.relative_class_cols])
|
|
681
|
-
try:
|
|
682
|
-
self.relative_class_cols.remove('class_color')
|
|
683
|
-
self.relative_class_cols.remove('class_id')
|
|
684
|
-
except:
|
|
685
|
-
pass
|
|
686
|
-
self.relative_class_choice_cb.currentIndexChanged.connect(self.compute_status_and_colors_pair)
|
|
687
|
-
self.relative_class_choice_cb.addItems(self.relative_class_cols)
|
|
688
|
-
idx = self.relative_class_choice_cb.findText(self.relative_class)
|
|
689
|
-
self.relative_class_choice_cb.setCurrentIndex(idx)
|
|
664
|
+
|
|
690
665
|
|
|
691
|
-
self.
|
|
666
|
+
self.extract_relevant_events()
|
|
692
667
|
|
|
668
|
+
self.pair_class_name = self.relative_class
|
|
693
669
|
self.pair_time_name = self.relative_time
|
|
694
670
|
self.pair_status_name = self.relative_status
|
|
695
671
|
|
|
@@ -705,167 +681,131 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
705
681
|
|
|
706
682
|
df_reference = self.dataframes[self.reference_population]
|
|
707
683
|
self.reference_class_name = self.reference_event_choice_cb.currentText()
|
|
708
|
-
self.expected_reference_status = 'status_'
|
|
709
|
-
suffix = self.reference_class_name.replace('class','').replace('_','')
|
|
710
|
-
if suffix!='':
|
|
711
|
-
self.expected_reference_status+='_'+suffix
|
|
712
|
-
self.expected_reference_time = 't_'+suffix
|
|
713
|
-
else:
|
|
714
|
-
self.expected_reference_time = 't0'
|
|
715
684
|
|
|
716
|
-
|
|
717
|
-
self.reference_status_name = self.expected_reference_status
|
|
685
|
+
if self.reference_class_name!='':
|
|
718
686
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
if not self.reference_status_name in list(df_reference.columns):
|
|
727
|
-
df_reference[self.reference_status_name] = 0
|
|
728
|
-
df_reference['status_color'] = color_from_status(0)
|
|
729
|
-
df_reference['class_color'] = color_from_class(1)
|
|
687
|
+
self.expected_reference_status = 'status_'
|
|
688
|
+
suffix = self.reference_class_name.replace('class','').replace('_','')
|
|
689
|
+
if suffix!='':
|
|
690
|
+
self.expected_reference_status+='_'+suffix
|
|
691
|
+
self.expected_reference_time = 't_'+suffix
|
|
692
|
+
else:
|
|
693
|
+
self.expected_reference_time = 't0'
|
|
730
694
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
if not self.reference_time_name in list(df_reference.columns):
|
|
734
|
-
df_reference[self.reference_time_name] = -1
|
|
695
|
+
self.reference_time_name = self.expected_reference_time
|
|
696
|
+
self.reference_status_name = self.expected_reference_status
|
|
735
697
|
|
|
736
|
-
|
|
737
|
-
|
|
698
|
+
if self.reference_time_name in list(df_reference.columns) and self.reference_class_name in list(df_reference.columns) and not self.reference_status_name in list(df_reference.columns):
|
|
699
|
+
# only create the status column if it does not exist to not erase static classification results
|
|
700
|
+
self.make_reference_status_column()
|
|
701
|
+
elif self.reference_time_name in list(df_reference.columns) and self.reference_class_name in list(df_reference.columns):
|
|
702
|
+
# all good, do nothing
|
|
703
|
+
pass
|
|
704
|
+
else:
|
|
705
|
+
if not self.reference_status_name in list(df_reference.columns):
|
|
706
|
+
df_reference[self.reference_status_name] = 0
|
|
707
|
+
df_reference['status_color'] = color_from_status(0)
|
|
708
|
+
df_reference['class_color'] = color_from_class(1)
|
|
738
709
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
710
|
+
if not self.reference_class_name in list(df_reference.columns):
|
|
711
|
+
df_reference[self.reference_class_name] = 1
|
|
712
|
+
if not self.reference_time_name in list(df_reference.columns):
|
|
713
|
+
df_reference[self.reference_time_name] = -1
|
|
714
|
+
|
|
715
|
+
df_reference['status_color'] = [color_from_status(i) for i in df_reference[self.reference_status_name].to_numpy()]
|
|
716
|
+
df_reference['class_color'] = [color_from_class(i) for i in df_reference[self.reference_class_name].to_numpy()]
|
|
717
|
+
|
|
718
|
+
if self.reference_population=='targets':
|
|
719
|
+
self.extract_scatter_from_target_trajectories()
|
|
720
|
+
else:
|
|
721
|
+
self.extract_scatter_from_effector_trajectories()
|
|
743
722
|
|
|
744
723
|
|
|
745
724
|
def compute_status_and_colors_neighbor(self):
|
|
746
725
|
|
|
747
726
|
df_neighbors = self.dataframes[self.neighbor_population]
|
|
748
727
|
self.neighbor_class_name = self.neighbor_event_choice_cb.currentText()
|
|
749
|
-
self.expected_neighbor_status = 'status_'
|
|
750
|
-
suffix = self.neighbor_class_name.replace('class','').replace('_','')
|
|
751
|
-
if suffix!='':
|
|
752
|
-
self.expected_neighbor_status+='_'+suffix
|
|
753
|
-
self.expected_neighbor_time = 't_'+suffix
|
|
754
|
-
else:
|
|
755
|
-
self.expected_neighbor_time = 't0'
|
|
756
728
|
|
|
757
|
-
|
|
758
|
-
self.neighbor_status_name = self.expected_neighbor_status
|
|
729
|
+
if self.neighbor_class_name!='':
|
|
759
730
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
if not self.neighbor_status_name in list(df_neighbors.columns):
|
|
768
|
-
df_neighbors[self.neighbor_status_name] = 0
|
|
769
|
-
df_neighbors['status_color'] = color_from_status(0)
|
|
770
|
-
df_neighbors['class_color'] = color_from_class(1)
|
|
731
|
+
self.expected_neighbor_status = 'status_'
|
|
732
|
+
suffix = self.neighbor_class_name.replace('class','').replace('_','')
|
|
733
|
+
if suffix!='':
|
|
734
|
+
self.expected_neighbor_status+='_'+suffix
|
|
735
|
+
self.expected_neighbor_time = 't_'+suffix
|
|
736
|
+
else:
|
|
737
|
+
self.expected_neighbor_time = 't0'
|
|
771
738
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
if not self.neighbor_time_name in list(df_neighbors.columns):
|
|
775
|
-
df_neighbors[self.neighbor_time_name] = -1
|
|
739
|
+
self.neighbor_time_name = self.expected_neighbor_time
|
|
740
|
+
self.neighbor_status_name = self.expected_neighbor_status
|
|
776
741
|
|
|
777
|
-
|
|
778
|
-
|
|
742
|
+
if self.neighbor_time_name in list(df_neighbors.columns) and self.neighbor_class_name in list(df_neighbors.columns) and not self.neighbor_status_name in list(df_neighbors.columns):
|
|
743
|
+
# only create the status column if it does not exist to not erase static classification results
|
|
744
|
+
self.make_neighbor_status_column()
|
|
745
|
+
elif self.neighbor_time_name in list(df_neighbors.columns) and self.neighbor_class_name in list(df_neighbors.columns):
|
|
746
|
+
# all good, do nothing
|
|
747
|
+
pass
|
|
748
|
+
else:
|
|
749
|
+
if not self.neighbor_status_name in list(df_neighbors.columns):
|
|
750
|
+
df_neighbors[self.neighbor_status_name] = 0
|
|
751
|
+
df_neighbors['status_color'] = color_from_status(0)
|
|
752
|
+
df_neighbors['class_color'] = color_from_class(1)
|
|
779
753
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
754
|
+
if not self.neighbor_class_name in list(df_neighbors.columns):
|
|
755
|
+
df_neighbors[self.neighbor_class_name] = 1
|
|
756
|
+
if not self.neighbor_time_name in list(df_neighbors.columns):
|
|
757
|
+
df_neighbors[self.neighbor_time_name] = -1
|
|
758
|
+
|
|
759
|
+
df_neighbors['status_color'] = [color_from_status(i) for i in df_neighbors[self.neighbor_status_name].to_numpy()]
|
|
760
|
+
df_neighbors['class_color'] = [color_from_class(i) for i in df_neighbors[self.neighbor_class_name].to_numpy()]
|
|
784
761
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
# self.effector_class_name = self.neighbor_event_choice_cb.currentText()
|
|
790
|
-
# else:
|
|
791
|
-
# self.effector_class_name=''
|
|
792
|
-
# #self.effector_class_name = self.effector_class_choice_cb.currentText()
|
|
793
|
-
# self.effector_expected_status = 'status'
|
|
794
|
-
# suffix = self.effector_class_name.replace('class','').replace('_','')
|
|
795
|
-
# if suffix!='':
|
|
796
|
-
# self.effector_expected_status+='_'+suffix
|
|
797
|
-
# self.effector_expected_time = 't_'+suffix
|
|
798
|
-
# else:
|
|
799
|
-
# self.effector_expected_time = 't0'
|
|
800
|
-
|
|
801
|
-
# self.effector_time_name = self.effector_expected_time
|
|
802
|
-
# self.effector_status_name = self.effector_expected_status
|
|
803
|
-
|
|
804
|
-
# print('selection and expected names: ', self.effector_class_name, self.effector_expected_time, self.effector_expected_status)
|
|
805
|
-
|
|
806
|
-
# if self.effector_time_name in self.df_effectors.columns and self.effector_class_name in self.df_effectors.columns and not self.effector_status_name in self.df_effectors.columns:
|
|
807
|
-
# # only create the status column if it does not exist to not erase static classification results
|
|
808
|
-
# self.make_effector_status_column()
|
|
809
|
-
# elif self.effector_time_name in self.df_effectors.columns and self.effector_class_name in self.df_effectors.columns:
|
|
810
|
-
# # all good, do nothing
|
|
811
|
-
# pass
|
|
812
|
-
# else:
|
|
813
|
-
# if not self.effector_status_name in self.df_effectors.columns:
|
|
814
|
-
# self.df_effectors[self.effector_status_name] = 0
|
|
815
|
-
# self.df_effectors['status_color'] = color_from_status(0)
|
|
816
|
-
# self.df_effectors['class_color'] = color_from_class(1)
|
|
817
|
-
|
|
818
|
-
# if not self.effector_class_name in self.df_effectors.columns:
|
|
819
|
-
# self.df_effectors[self.effector_class_name] = 1
|
|
820
|
-
# if not self.effector_time_name in self.df_effectors.columns:
|
|
821
|
-
# self.df_effectors[self.effector_time_name] = -1
|
|
822
|
-
|
|
823
|
-
# self.df_effectors['status_color'] = [color_from_status(i) for i in self.df_effectors[self.effector_status_name].to_numpy()]
|
|
824
|
-
# self.df_effectors['class_color'] = [color_from_class(i) for i in self.df_effectors[self.effector_class_name].to_numpy()]
|
|
825
|
-
|
|
826
|
-
# self.extract_scatter_from_effector_trajectories()
|
|
762
|
+
if self.neighbor_population=='targets':
|
|
763
|
+
self.extract_scatter_from_target_trajectories()
|
|
764
|
+
else:
|
|
765
|
+
self.extract_scatter_from_effector_trajectories()
|
|
827
766
|
|
|
828
767
|
def compute_status_and_colors_pair(self):
|
|
829
768
|
|
|
830
769
|
self.pair_class_name = self.relative_class_choice_cb.currentText()
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
self.pair_expected_time
|
|
840
|
-
|
|
841
|
-
|
|
770
|
+
|
|
771
|
+
if self.pair_class_name!='':
|
|
772
|
+
|
|
773
|
+
self.pair_expected_status = 'status'
|
|
774
|
+
suffix = self.pair_class_name.replace('class','').replace('_','',1)
|
|
775
|
+
if suffix!='':
|
|
776
|
+
self.pair_expected_status+='_'+suffix
|
|
777
|
+
self.pair_expected_time = 't0_'+suffix
|
|
778
|
+
if not self.pair_expected_time in list(self.df_relative.columns):
|
|
779
|
+
self.pair_expected_time = 't_'+suffix
|
|
780
|
+
else:
|
|
781
|
+
self.pair_expected_time = 't0'
|
|
842
782
|
|
|
843
|
-
|
|
844
|
-
|
|
783
|
+
self.pair_time_name = self.pair_expected_time
|
|
784
|
+
self.pair_status_name = self.pair_expected_status
|
|
845
785
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
786
|
+
if self.pair_time_name in self.df_relative.columns and self.pair_class_name in self.df_relative.columns and not self.pair_status_name in self.df_relative.columns:
|
|
787
|
+
# only create the status column if it does not exist to not erase static classification results
|
|
788
|
+
self.make_relative_status_column()
|
|
789
|
+
elif self.pair_time_name in self.df_relative.columns and self.pair_class_name in self.df_relative.columns:
|
|
790
|
+
# all good, do nothing
|
|
791
|
+
pass
|
|
792
|
+
else:
|
|
793
|
+
if not self.pair_status_name in self.df_relative.columns:
|
|
794
|
+
self.df_relative[self.pair_status_name] = 0
|
|
795
|
+
self.df_relative['status_color'] = color_from_status(0)
|
|
796
|
+
self.df_relative['class_color'] = color_from_class(1)
|
|
857
797
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
798
|
+
if not self.pair_class_name in self.df_relative.columns:
|
|
799
|
+
self.df_relative[self.pair_time_name] = 1
|
|
800
|
+
if not self.pair_time_name in self.df_relative.columns:
|
|
801
|
+
self.df_relative[self.pair_time_name] = -1
|
|
862
802
|
|
|
863
|
-
|
|
864
|
-
|
|
803
|
+
self.df_relative['status_color'] = [color_from_status(i) for i in self.df_relative[self.pair_status_name].to_numpy()]
|
|
804
|
+
self.df_relative['class_color'] = [color_from_class(i) for i in self.df_relative[self.pair_class_name].to_numpy()]
|
|
865
805
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
806
|
+
self.extract_scatter_from_lines()
|
|
807
|
+
self.give_pair_information()
|
|
808
|
+
self.plot_signals()
|
|
869
809
|
|
|
870
810
|
def contrast_slider_action(self):
|
|
871
811
|
|
|
@@ -1329,30 +1269,6 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
1329
1269
|
self.MinMaxScaler_effectors.fit(x)
|
|
1330
1270
|
|
|
1331
1271
|
|
|
1332
|
-
# def make_effector_status_column(self):
|
|
1333
|
-
# print('remaking the status column for the effectors')
|
|
1334
|
-
# for tid, group in self.df_effectors.groupby('TRACK_ID'):
|
|
1335
|
-
|
|
1336
|
-
# indices = group.index
|
|
1337
|
-
# t0 = group[self.].to_numpy()[0]
|
|
1338
|
-
# cclass = group[self.class_name].to_numpy()[0]
|
|
1339
|
-
# timeline = group['FRAME'].to_numpy()
|
|
1340
|
-
# status = np.zeros_like(timeline)
|
|
1341
|
-
# if t0 > 0:
|
|
1342
|
-
# status[timeline >= t0] = 1.
|
|
1343
|
-
# if cclass == 2:
|
|
1344
|
-
# status[:] = 2
|
|
1345
|
-
# if cclass > 2:
|
|
1346
|
-
# status[:] = 42
|
|
1347
|
-
# status_color = [color_from_status(s) for s in status]
|
|
1348
|
-
# class_color = [color_from_class(cclass) for i in range(len(status))]
|
|
1349
|
-
|
|
1350
|
-
# self.df_tracks.loc[indices, self.status_name] = status
|
|
1351
|
-
# self.df_tracks.loc[indices, 'status_color'] = status_color
|
|
1352
|
-
# self.df_tracks.loc[indices, 'class_color'] = class_color
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
1272
|
def locate_relative_tracks(self):
|
|
1357
1273
|
|
|
1358
1274
|
population = 'relative'
|
|
@@ -1392,6 +1308,9 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
1392
1308
|
self.relative_time_name = 't0'
|
|
1393
1309
|
self.relative_status_name = 'status'
|
|
1394
1310
|
|
|
1311
|
+
for col in list(self.df_relative.columns):
|
|
1312
|
+
if np.all(self.df_relative[col].isnull()) or self.df_relative[col].dtype==object:
|
|
1313
|
+
self.cols_to_remove.append(col)
|
|
1395
1314
|
|
|
1396
1315
|
self.MinMaxScaler_pairs = MinMaxScaler()
|
|
1397
1316
|
self.pair_columns = list(self.df_relative.columns)
|
|
@@ -1408,7 +1327,7 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
1408
1327
|
pass
|
|
1409
1328
|
|
|
1410
1329
|
x = self.df_relative[self.pair_columns].values
|
|
1411
|
-
self.MinMaxScaler_pairs.fit(x)
|
|
1330
|
+
self.MinMaxScaler_pairs.fit(x)
|
|
1412
1331
|
|
|
1413
1332
|
|
|
1414
1333
|
def set_reference_and_neighbor_populations(self):
|
|
@@ -1813,6 +1732,7 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
1813
1732
|
self.cancel_selection()
|
|
1814
1733
|
self.set_reference_and_neighbor_populations()
|
|
1815
1734
|
# Update reference classes and neighbor classes
|
|
1735
|
+
self.extract_relevant_events()
|
|
1816
1736
|
self.fill_class_cbs()
|
|
1817
1737
|
|
|
1818
1738
|
self.update_cell_events()
|
|
@@ -1820,6 +1740,39 @@ class SignalAnnotator2(QMainWindow,Styles):
|
|
|
1820
1740
|
# self.draw_frame(self.framedata)
|
|
1821
1741
|
self.plot_signals()
|
|
1822
1742
|
|
|
1743
|
+
def extract_relevant_events(self):
|
|
1744
|
+
|
|
1745
|
+
if self.reference_population!=self.neighbor_population:
|
|
1746
|
+
pattern = "_2_"
|
|
1747
|
+
else:
|
|
1748
|
+
pattern = "_self_"
|
|
1749
|
+
|
|
1750
|
+
try:
|
|
1751
|
+
self.relative_class_choice_cb.disconnect()
|
|
1752
|
+
except:
|
|
1753
|
+
pass
|
|
1754
|
+
|
|
1755
|
+
self.relative_class_choice_cb.clear()
|
|
1756
|
+
|
|
1757
|
+
cols = list(self.df_relative.columns)
|
|
1758
|
+
self.relative_class_cols = [c for c in cols if c.startswith('class')]
|
|
1759
|
+
for c in ['class_color', 'class_id']:
|
|
1760
|
+
if c in self.relative_class_cols:
|
|
1761
|
+
self.relative_class_cols.remove(c)
|
|
1762
|
+
|
|
1763
|
+
# Keep only valid classes for which there are values
|
|
1764
|
+
self.new_relative_class_cols = []
|
|
1765
|
+
for c in self.relative_class_cols:
|
|
1766
|
+
if ~self.df_relative.loc[(self.df_relative['reference_population']==self.reference_population)&(self.df_relative['neighbor_population']==self.neighbor_population),c].isnull().all():
|
|
1767
|
+
self.new_relative_class_cols.append(c)
|
|
1768
|
+
|
|
1769
|
+
if len(self.new_relative_class_cols)>0:
|
|
1770
|
+
self.relative_class = self.new_relative_class_cols[0]
|
|
1771
|
+
self.relative_class_choice_cb.currentIndexChanged.connect(self.compute_status_and_colors_pair)
|
|
1772
|
+
self.relative_class_choice_cb.addItems(self.new_relative_class_cols)
|
|
1773
|
+
idx = self.relative_class_choice_cb.findText(self.relative_class)
|
|
1774
|
+
self.relative_class_choice_cb.setCurrentIndex(idx)
|
|
1775
|
+
|
|
1823
1776
|
|
|
1824
1777
|
def closeEvent(self, event):
|
|
1825
1778
|
|