1010from ibllib .atlas import AllenAtlas , regions
1111import qt
1212
13+ from PyQt5 import Qt
14+ import vedo
15+ from vtk .qt .QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
16+ from oneibl .one import ONE
17+ #one = ONE()
18+ from ibllib .pipes .histology import coverage
19+ from needles2 .needles_viewer import NeedlesViewer
1320
1421class MainWindow (QtWidgets .QMainWindow ):
1522
@@ -38,6 +45,19 @@ def __init__(self):
3845
3946 self .atlas = AllenAtlas (25 )
4047 main_layout = QtWidgets .QGridLayout ()
48+ self .frame = Qt .QFrame ()
49+ self .vl = Qt .QVBoxLayout ()
50+ self .vtkWidget = QVTKRenderWindowInteractor (self .frame )
51+ self .vl .addWidget (self .vtkWidget )
52+ self .plt = vedo .Plotter (qtWidget = self .vtkWidget , N = 1 )
53+ self .la = NeedlesViewer ()
54+ self .la .initialize (self .plt )
55+ print (self .la )
56+ self .la2 = NeedlesViewer ()
57+ self .la2 .initialize (self .plt )
58+ self .frame .setLayout (self .vl )
59+
60+
4161 self .coronal = SliceView (self , self .atlas , waxis = 0 , haxis = 2 , daxis = 1 )
4262 self .sagittal = SliceView (self , self .atlas , waxis = 1 , haxis = 2 , daxis = 0 )
4363 self .top = TopView (self , self .atlas )
@@ -61,6 +81,12 @@ def __init__(self):
6181 images = ['Image' , 'Annotation' ]
6282 self .add_menu_bar (self .img_menu , self .img_group , images , callback = self .change_image )
6383
84+ # Add menu bar for coverage
85+ self .coverage_menu = menu_bar .addMenu ('Coverage' )
86+ self .coverage_group = QtGui .QActionGroup (self .coverage_menu )
87+ self .coverage_group .setExclusive (True )
88+ self .add_menu_bar (self .img_menu , self .img_group , ['Coverage' ], callback = self .change_image )
89+
6490 self .region_list = QtGui .QStandardItemModel ()
6591 self .region_combobox = QtWidgets .QComboBox ()
6692 # Add line edit and completer to be able to search for subject
@@ -70,23 +96,24 @@ def __init__(self):
7096 self .region_combobox .setCompleter (region_completer )
7197 self .region_combobox .setModel (self .region_list )
7298 self .region_combobox .completer ().setModel (self .region_list )
73- data = self .atlas .regions .name [self .atlas ._get_mapping (mapping = self .get_mapping ())]
74- self .populate_lists (data , self .region_list , self .region_combobox )
75-
7699 self .region_combobox .activated .connect (self .on_region_selected )
100+ self .change_mapping ()
101+
77102
103+ offset = self .atlas .bc .lim (0 )[0 ]
104+ self .la .update_slicer (self .la .nx_slicer , self .top .line_sagittal .value ()* 1e6 + offset * 1e6 )
78105
79106 main_layout .addWidget (self .region_combobox )
80107 main_layout .addWidget (self .top )
81108 main_layout .addWidget (self .coronal )
82109 main_layout .addWidget (self .sagittal )
110+ main_layout .addWidget (self .frame )
83111 main_widget .setLayout (main_layout )
84112
85113 # initialise
86114 self .set_slice (self .coronal )
87115 self .set_slice (self .sagittal )
88- # menu bar for mapping
89- # menu bar for image type
116+
90117
91118 def populate_lists (self , data , list_name , combobox ):
92119 """
@@ -104,7 +131,7 @@ def populate_lists(self, data, list_name, combobox):
104131 item .setEditable (False )
105132 list_name .appendRow (item )
106133
107- # This makes sure the drop down menu is wide enough to showw full length of string
134+ # This makes sure the drop down menu is wide enough to show full length of string
108135 min_width = combobox .fontMetrics ().width (max (data , key = len ))
109136 min_width += combobox .view ().autoScrollMargin ()
110137 min_width += combobox .style ().pixelMetric (QtGui .QStyle .PM_ScrollBarExtent )
@@ -114,7 +141,8 @@ def populate_lists(self, data, list_name, combobox):
114141 combobox .setCurrentIndex (0 )
115142
116143 def change_mapping (self ):
117- data = self .atlas .regions .name [self .atlas ._get_mapping (mapping = self .get_mapping ())]
144+ data = np .unique (self .atlas .regions .name [self .atlas ._get_mapping (
145+ mapping = self .get_mapping ())])
118146 self .populate_lists (data , self .region_list , self .region_combobox )
119147 self ._refresh ()
120148
@@ -128,6 +156,14 @@ def change_image(self):
128156 self .img_group .checkedAction ().text ())
129157 self ._refresh ()
130158
159+ def add_coverage (self ):
160+ traj = one .alyx .rest ('trajectories' , 'list' , provenance = 'Ephys aligned histology track' )
161+ self .coverage = coverage (traj , self .atlas )
162+ self .coronal .ctrl .add_volume_layer (self .coronal .fig_slice , self .coverage )
163+ self .sagittal .ctrl .add_volume_layer (self .sagittal .fig_slice , self .coverage )
164+ self ._refresh ()
165+
166+
131167 def add_menu_bar (self , menu , group , items , callback = None , default = None ):
132168 if not default :
133169 default = items [0 ]
@@ -176,9 +212,13 @@ def _refresh(self):
176212
177213 def _refresh_coronal (self ):
178214 self .set_slice (self .coronal , self .top .line_coronal .value ())
215+ offset = self .atlas .bc .lim (1 )[1 ]
216+ self .la .update_slicer (self .la .ny_slicer , (self .top .line_coronal .value ()* 1e6 + offset * 16 ))
179217
180218 def _refresh_sagittal (self ):
181219 self .set_slice (self .sagittal , self .top .line_sagittal .value ())
220+ offset = self .atlas .bc .lim (0 )[0 ]
221+ self .la .update_slicer (self .la .nx_slicer , self .top .line_sagittal .value ()* 1e6 + offset * 1e6 )
182222
183223 def _refresh_locked_region (self , region ):
184224 region_values = np .zeros_like (self .atlas .regions .id )
@@ -197,6 +237,7 @@ def _refresh_locked_region(self, region):
197237 self ._refresh ()
198238 self .set_selected_region (region )
199239 # need to set the drop down to the selected region
240+ self .la .reveal_regions (region_idx )
200241
201242 def _reset_region (self , name ):
202243 region_values = np .zeros_like (self .atlas .regions .id )
@@ -282,13 +323,13 @@ def __init__(self, qmain: MainWindow, atlas: AllenAtlas, waxis, haxis, daxis):
282323 label_layout .addWidget (self .label_ix )
283324 label_layout .addWidget (self .label_iy )
284325 label_layout .addWidget (self .label_v )
285- label_layout .addWidget (self .label_region )
326+ # label_layout.addWidget(self.label_region)
286327 label_layout .addWidget (self .label_acronym )
287328 label_group .setLayout (label_layout )
288329
289330
290- main_layout .addWidget (self .fig_slice )
291- main_layout .addWidget (label_group )
331+ main_layout .addWidget (self .fig_slice , 0 , 0 )
332+ main_layout .addWidget (label_group , 0 , 1 )
292333 self .setLayout (main_layout )
293334
294335 # init the image display
@@ -332,7 +373,7 @@ def mouseMoveEvent(self, scenepos):
332373 self .label_acronym .setText ("" )
333374 self .qmain ._reset_region ('non_locked' )
334375 else :
335- self .label_region .setText (region ['name' ][0 ])
376+ # self.label_region.setText(region['name'][0])
336377 self .label_acronym .setText (region ['acronym' ][0 ])
337378
338379 if region ['acronym' ][0 ] != 'void' :
@@ -414,6 +455,15 @@ def add_mask_layer(self, fig, name='locked', cmap='Blues'):
414455 'volume' : 'value' , 'region_values' : np .zeros_like (self .atlas .regions .id ),
415456 'mode' : 'clip' })
416457
458+ def add_volume_layer (self , fig , volume , name = 'coverage' , cmap = 'viridis' ):
459+ colormap = matplotlib .cm .get_cmap (cmap )
460+ colormap ._init ()
461+ # The last one is [0, 0, 0, 0] so remove this
462+ lut = (colormap ._lut * 255 ).view (np .ndarray )[:- 1 ]
463+ lut = np .insert (lut , 0 , [0 , 0 , 0 , 0 ], axis = 0 )
464+ self .add_image_layer (fig , name = name , pg_kwargs = {'lut' : lut , 'opacity' : 0.8 }, slice_kwargs = {
465+ 'volume' : 'volume' , 'region_values' : volume , 'mode' : 'clip' })
466+
417467 def change_base_layer (self , fig , image = 'Image' ):
418468 base_layer = self .get_image_layer (name = 'base' )
419469 if image == 'Image' :
0 commit comments