diff --git a/brainrender_napari/brainrender_widget.py b/brainrender_napari/brainrender_widget.py index fb80364..510cf5b 100644 --- a/brainrender_napari/brainrender_widget.py +++ b/brainrender_napari/brainrender_widget.py @@ -20,6 +20,7 @@ from brainrender_napari.napari_atlas_representation import ( NapariAtlasRepresentation, ) +from brainrender_napari.utils.from_viewer import structure_from_viewer from brainrender_napari.widgets.atlas_table_view import AtlasTableView from brainrender_napari.widgets.structure_view import StructureView @@ -97,6 +98,31 @@ def __init__(self, napari_viewer: Viewer): self._on_add_structure_requested ) + @self._viewer.mouse_move_callbacks.append + def display_region_info(v, event): + """ + Show brain region info on mouse over in status bar on the right + """ + assert self._viewer == v + self.annotations_layer = self._viewer.layers[ + -1 + ] # temporary hacks!! + self.atlas = BrainGlobeAtlas("allen_mouse_100um") + if v.dims.ndisplay == 2: + if len(v.layers) and self.annotations_layer and self.atlas: + _, _, _, region_info = structure_from_viewer( + self._viewer.cursor.position, + self.annotations_layer, + self.atlas, + ) + self._viewer.tooltip.visible = True + self._viewer.tooltip.text = region_info + else: + self._viewer.help = "" + + print("annotations", self.annotations_layer) + print("help", self._viewer.help) + def _on_download_atlas_confirmed(self, atlas_name): """Ensure structure view is displayed if new atlas downloaded.""" show_structure_names = self.show_structure_names.isChecked() diff --git a/brainrender_napari/utils/from_viewer.py b/brainrender_napari/utils/from_viewer.py new file mode 100644 index 0000000..d91ff16 --- /dev/null +++ b/brainrender_napari/utils/from_viewer.py @@ -0,0 +1,63 @@ +def structure_from_viewer(coordinates, atlas_layer, atlas): + """ + Get brain region info from mouse position in napari viewer. + + Return brainglobe (BG) structure number, name, hemisphere, and a + "pretty" string that can be displayed for example in the status bar. + + Parameter + --------- + coordinates : tuple, nx3 coordinate of cursor position, from + Viewer.cursor.position + atlas_layer : Napari viewer layer + Layer, which contains the annotation / region + information for every structure in the (registered) + atlas + atlas : Brainglobe atlas (bg_atlasapi.bg_atlas.BrainGlobeAtlas) + + Returns + ------- + + region_info : str + A string containing info about structure + and hemisphere + Returns empty string if not found + """ + + # Using a regex, extract list of coordinates from status string + assert hasattr(atlas_layer, "data"), "Atlas layer appears to be empty" + assert atlas_layer.data.ndim == 3, ( + "Atlas layer data does not have the right dim " + f'("{atlas_layer.data.ndim}")' + ) + + coord_list = tuple( + [int(x / r) for x, r in zip(coordinates, atlas.resolution)] + ) + + # Extract structure number + try: + structure_no = atlas_layer.data[coord_list] + except IndexError: + return None, None, None, "" + + if structure_no in [0]: # 0 is "Null" region + return None, None, None, "" + + # Extract structure information + try: + structure = atlas.structures[structure_no]["name"] + except KeyError: + return None, None, None, "" + + # ... and make string pretty + region_info = [] + for struct in structure.split(","): + region_info.append(struct.strip().capitalize()) + hemisphere = atlas.hemisphere_from_coords( + coord_list, as_string=True + ).capitalize() + region_info.append(hemisphere) + region_info = " | ".join(region_info) + + return structure_no, structure, hemisphere, region_info