From e2cdde4930e00321483a98ff66d98f2ce11e3e17 Mon Sep 17 00:00:00 2001 From: alessandrofelder Date: Wed, 24 Jul 2024 15:45:05 +0100 Subject: [PATCH 1/6] rename viewer widget --- ...widget.py => brainrender_viewer_widget.py} | 2 +- ...t.py => test_brainrender_viewer_widget.py} | 60 +++++++++---------- 2 files changed, 30 insertions(+), 32 deletions(-) rename brainrender_napari/{brainrender_widget.py => brainrender_viewer_widget.py} (99%) rename tests/test_integration/{test_brainrender_widget.py => test_brainrender_viewer_widget.py} (64%) diff --git a/brainrender_napari/brainrender_widget.py b/brainrender_napari/brainrender_viewer_widget.py similarity index 99% rename from brainrender_napari/brainrender_widget.py rename to brainrender_napari/brainrender_viewer_widget.py index de776a7..8254be8 100644 --- a/brainrender_napari/brainrender_widget.py +++ b/brainrender_napari/brainrender_viewer_widget.py @@ -26,7 +26,7 @@ from brainrender_napari.widgets.structure_view import StructureView -class BrainrenderWidget(QWidget): +class BrainrenderViewerWidget(QWidget): """The purpose of this class is * to hold atlas visualisation widgets for napari * coordinate between these widgets and napari diff --git a/tests/test_integration/test_brainrender_widget.py b/tests/test_integration/test_brainrender_viewer_widget.py similarity index 64% rename from tests/test_integration/test_brainrender_widget.py rename to tests/test_integration/test_brainrender_viewer_widget.py index e0a8d2c..bd9b248 100644 --- a/tests/test_integration/test_brainrender_widget.py +++ b/tests/test_integration/test_brainrender_viewer_widget.py @@ -4,17 +4,19 @@ import pytest -from brainrender_napari.brainrender_widget import BrainrenderWidget +from brainrender_napari.brainrender_viewer_widget import ( + BrainrenderViewerWidget, +) @pytest.fixture -def brainrender_widget(make_napari_viewer) -> BrainrenderWidget: +def viewer_widget(make_napari_viewer) -> BrainrenderViewerWidget: """Fixture to expose the atlas viewer widget to tests. Simultaneously acts as a smoke test that the widget can be instantiated without crashing.""" viewer = make_napari_viewer() - return BrainrenderWidget(viewer) + return BrainrenderViewerWidget(viewer) @pytest.mark.parametrize( @@ -25,12 +27,12 @@ def brainrender_widget(make_napari_viewer) -> BrainrenderWidget: ], ) def test_checkbox_visibility( - brainrender_widget, mocker, expected_visibility, atlas + viewer_widget, mocker, expected_visibility, atlas ): checkbox_visibility_mock = mocker.patch( - "brainrender_napari.brainrender_widget.QCheckBox.setVisible" + "brainrender_napari.brainrender_viewer_widget.QCheckBox.setVisible" ) - brainrender_widget._on_atlas_selection_changed(atlas) + viewer_widget._on_atlas_selection_changed(atlas) checkbox_visibility_mock.assert_called_once_with(expected_visibility) @@ -43,58 +45,54 @@ def test_checkbox_visibility( ], ) def test_double_click_on_locally_available_atlas_row( - brainrender_widget, mocker, qtbot, expected_atlas_name + viewer_widget, mocker, qtbot, expected_atlas_name ): """Check for a few local low-res atlases that double-clicking them on the atlas viewer view calls the expected atlas representation function. """ add_atlas_to_viewer_mock = mocker.patch( - "brainrender_napari.brainrender_widget" + "brainrender_napari.brainrender_viewer_widget" ".NapariAtlasRepresentation.add_to_viewer" ) - with qtbot.waitSignal( - brainrender_widget.atlas_viewer_view.add_atlas_requested - ): - brainrender_widget.atlas_viewer_view.add_atlas_requested.emit( + with qtbot.waitSignal(viewer_widget.atlas_viewer_view.add_atlas_requested): + viewer_widget.atlas_viewer_view.add_atlas_requested.emit( expected_atlas_name ) add_atlas_to_viewer_mock.assert_called_once() -def test_structure_row_double_clicked(brainrender_widget, mocker): +def test_structure_row_double_clicked(viewer_widget, mocker): """Checks that when the structure view widgets emit "VS" and the allen_mouse_100um atlas is selected, the NapariAtlasRepresentation function is called in the expected way. """ add_structure_to_viewer_mock = mocker.patch( - "brainrender_napari.brainrender_widget" + "brainrender_napari.brainrender_viewer_widget" ".NapariAtlasRepresentation.add_structure_to_viewer" ) - brainrender_widget.atlas_viewer_view.selectRow( + viewer_widget.atlas_viewer_view.selectRow( 4 ) # allen_mouse_100um is in row 4 - brainrender_widget.structure_view.add_structure_requested.emit("VS") + viewer_widget.structure_view.add_structure_requested.emit("VS") add_structure_to_viewer_mock.assert_called_once_with("VS") -def test_add_additional_reference_selected(brainrender_widget, mocker): +def test_add_additional_reference_selected(viewer_widget, mocker): """Checks that when the atlas viewer view requests an additional reference, the NapariAtlasRepresentation function is called in the expected way.""" add_additional_reference_mock = mocker.patch( - "brainrender_napari.brainrender_widget" + "brainrender_napari.brainrender_viewer_widget" ".NapariAtlasRepresentation.add_additional_reference" ) - brainrender_widget.atlas_viewer_view.selectRow( - 5 - ) # mpin_zfish_1um is in row 5 + viewer_widget.atlas_viewer_view.selectRow(5) # mpin_zfish_1um is in row 5 assert ( - brainrender_widget.atlas_viewer_view.selected_atlas_name() + viewer_widget.atlas_viewer_view.selected_atlas_name() == "mpin_zfish_1um" ) additional_reference_name = "GAD1b" - brainrender_widget.atlas_viewer_view.additional_reference_requested.emit( + viewer_widget.atlas_viewer_view.additional_reference_requested.emit( additional_reference_name ) add_additional_reference_mock.assert_called_once_with( @@ -102,23 +100,23 @@ def test_add_additional_reference_selected(brainrender_widget, mocker): ) -def test_show_structures_checkbox(brainrender_widget, mocker): +def test_show_structures_checkbox(viewer_widget, mocker): structure_view_refresh_mock = mocker.patch( - "brainrender_napari.brainrender_widget.StructureView.refresh" + "brainrender_napari.brainrender_viewer_widget.StructureView.refresh" ) - brainrender_widget.atlas_viewer_view.selectRow( + viewer_widget.atlas_viewer_view.selectRow( 0 ) # example_mouse_100um is in row 0 structure_view_refresh_mock.assert_called_with( "example_mouse_100um", False ) - brainrender_widget.show_structure_names.click() + viewer_widget.show_structure_names.click() assert structure_view_refresh_mock.call_count == 2 structure_view_refresh_mock.assert_called_with("example_mouse_100um", True) -def test_structure_view_tooltip(brainrender_widget): +def test_structure_view_tooltip(viewer_widget): for expected_keyword in [ "double-click", "atlas region", @@ -131,11 +129,11 @@ def test_structure_view_tooltip(brainrender_widget): ]: assert ( expected_keyword - in brainrender_widget.structure_tree_group.toolTip().lower() + in viewer_widget.structure_tree_group.toolTip().lower() ) -def test_atlas_viewer_view_tooltip(brainrender_widget): +def test_atlas_viewer_view_tooltip(viewer_widget): for expected_keyword in [ "double-click", "add", @@ -146,5 +144,5 @@ def test_atlas_viewer_view_tooltip(brainrender_widget): ]: assert ( expected_keyword - in brainrender_widget.atlas_viewer_group.toolTip().lower() + in viewer_widget.atlas_viewer_group.toolTip().lower() ) From 00a2e163cb78dae0619246ed16e699eef644719b Mon Sep 17 00:00:00 2001 From: alessandrofelder Date: Wed, 24 Jul 2024 15:47:08 +0100 Subject: [PATCH 2/6] add manager widget --- .../brainrender_manager_widget.py | 54 +++++++++++++++++++ .../test_brainrender_manager_widget.py | 32 +++++++++++ 2 files changed, 86 insertions(+) create mode 100644 brainrender_napari/brainrender_manager_widget.py create mode 100644 tests/test_integration/test_brainrender_manager_widget.py diff --git a/brainrender_napari/brainrender_manager_widget.py b/brainrender_napari/brainrender_manager_widget.py new file mode 100644 index 0000000..22480af --- /dev/null +++ b/brainrender_napari/brainrender_manager_widget.py @@ -0,0 +1,54 @@ +""" +A napari widget to download and update atlases. + +Available atlases are shown in a table view using the Qt model/view framework +[Qt Model/View framework](https://doc.qt.io/qt-6/model-view-programming.html) +""" + +from brainglobe_utils.qtpy.logo import header_widget +from napari.viewer import Viewer +from qtpy.QtWidgets import ( + QGroupBox, + QVBoxLayout, + QWidget, +) + +from brainrender_napari.widgets.atlas_manager_view import AtlasManagerView + + +class BrainrenderManagerWidget(QWidget): + """The purpose of this class is + * to hold atlas visualisation widgets for napari + * coordinate between these widgets and napari + """ + + def __init__(self, napari_viewer: Viewer): + """Instantiates the atlas viewer widget + and sets up coordinating connections""" + super().__init__() + + self._viewer = napari_viewer + self.setLayout(QVBoxLayout()) + self.layout().addWidget( + header_widget( + "brainrender", + "Atlas management", + tutorial_file_name="manage-atlas-napari.html", + citation_doi="https://doi.org/10.7554/eLife.65751", + github_repo_name="brainrender-napari", + help_text="For help, hover the cursor over the " + "atlases/regions.", + ) + ) + + # create widgets + self.atlas_manager_view = AtlasManagerView(parent=self) + + # add widgets to the layout as group boxes + self.atlas_manager_group = QGroupBox("Atlas Manager") + self.atlas_manager_group.setToolTip( + "Double-click on row to download/update an atlas" + ) + self.atlas_manager_group.setLayout(QVBoxLayout()) + self.atlas_manager_group.layout().addWidget(self.atlas_manager_view) + self.layout().addWidget(self.atlas_manager_group) diff --git a/tests/test_integration/test_brainrender_manager_widget.py b/tests/test_integration/test_brainrender_manager_widget.py new file mode 100644 index 0000000..37c0f82 --- /dev/null +++ b/tests/test_integration/test_brainrender_manager_widget.py @@ -0,0 +1,32 @@ +"""These tests should just check that the subwidget signal and napari +are connected as expected. Lower level tests should happen in the tests +for the widget themselves.""" + +import pytest + +from brainrender_napari.brainrender_manager_widget import ( + BrainrenderManagerWidget, +) + + +@pytest.fixture +def manager_widget(make_napari_viewer) -> BrainrenderManagerWidget: + """Fixture to expose the atlas viewer widget to tests. + + Simultaneously acts as a smoke test that the widget + can be instantiated without crashing.""" + viewer = make_napari_viewer() + return BrainrenderManagerWidget(viewer) + + +def test_atlas_viewer_view_tooltip(manager_widget): + for expected_keyword in [ + "double-click", + "download/update", + "row", + "atlas", + ]: + assert ( + expected_keyword + in manager_widget.atlas_viewer_group.toolTip().lower() + ) From c97c8d00e07efbbde14e686a2166b5d9b444c114 Mon Sep 17 00:00:00 2001 From: alessandrofelder Date: Wed, 24 Jul 2024 15:47:34 +0100 Subject: [PATCH 3/6] sort hooking up to napari --- brainrender_napari/__init__.py | 2 +- brainrender_napari/napari.yaml | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/brainrender_napari/__init__.py b/brainrender_napari/__init__.py index 5a57962..3d4fafe 100644 --- a/brainrender_napari/__init__.py +++ b/brainrender_napari/__init__.py @@ -1,4 +1,4 @@ __version__ = "0.0.1" -__all__ = "BrainrenderWidget" +__all__ = "BrainrenderViewerWidget, BrainrenderManagerWidget" diff --git a/brainrender_napari/napari.yaml b/brainrender_napari/napari.yaml index f4415b3..146d041 100644 --- a/brainrender_napari/napari.yaml +++ b/brainrender_napari/napari.yaml @@ -2,9 +2,14 @@ name: brainrender-napari display_name: brainrender contributions: commands: - - id: brainrender-napari.make_brainrender_widget - python_name: brainrender_napari.brainrender_widget:BrainrenderWidget - title: Make Brainrender Napari + - id: brainrender-napari.make_brainrender_viewer_widget + python_name: brainrender_napari.brainrender_viewer_widget:BrainrenderViewerWidget + title: Make Brainrender Napari Viewer + - id: brainrender-napari.make_brainrender_manager_widget + python_name: brainrender_napari.brainrender_manager_widget:BrainrenderManagerWidget + title: Make Brainrender Napari Manager widgets: - - command: brainrender-napari.make_brainrender_widget - display_name: Brainrender + - command: brainrender-napari.make_brainrender_viewer_widget + display_name: Brainrender (visualise) + - command: brainrender-napari.make_brainrender_manager_widget + display_name: Brainrender (manage) From 06f3efda077819cd0bfaafd3084053499726cb8b Mon Sep 17 00:00:00 2001 From: alessandrofelder Date: Wed, 24 Jul 2024 15:49:38 +0100 Subject: [PATCH 4/6] fix typo in manager widget test --- tests/test_integration/test_brainrender_manager_widget.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_integration/test_brainrender_manager_widget.py b/tests/test_integration/test_brainrender_manager_widget.py index 37c0f82..702e0dd 100644 --- a/tests/test_integration/test_brainrender_manager_widget.py +++ b/tests/test_integration/test_brainrender_manager_widget.py @@ -19,7 +19,7 @@ def manager_widget(make_napari_viewer) -> BrainrenderManagerWidget: return BrainrenderManagerWidget(viewer) -def test_atlas_viewer_view_tooltip(manager_widget): +def test_atlas_manager_view_tooltip(manager_widget): for expected_keyword in [ "double-click", "download/update", @@ -28,5 +28,5 @@ def test_atlas_viewer_view_tooltip(manager_widget): ]: assert ( expected_keyword - in manager_widget.atlas_viewer_group.toolTip().lower() + in manager_widget.atlas_manager_group.toolTip().lower() ) From c3980a25868ea28ae770ea7f652adc9eee3f2dc2 Mon Sep 17 00:00:00 2001 From: alessandrofelder Date: Wed, 24 Jul 2024 18:08:05 +0100 Subject: [PATCH 5/6] clarify widget header text --- brainrender_napari/napari.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brainrender_napari/napari.yaml b/brainrender_napari/napari.yaml index 146d041..1e7fb67 100644 --- a/brainrender_napari/napari.yaml +++ b/brainrender_napari/napari.yaml @@ -10,6 +10,6 @@ contributions: title: Make Brainrender Napari Manager widgets: - command: brainrender-napari.make_brainrender_viewer_widget - display_name: Brainrender (visualise) + display_name: Brainrender - command: brainrender-napari.make_brainrender_manager_widget - display_name: Brainrender (manage) + display_name: Manage atlas versions From 0deb9b026a0fb809fa19bd984dbfcf83da3e5dd3 Mon Sep 17 00:00:00 2001 From: alessandrofelder Date: Thu, 25 Jul 2024 17:50:34 +0100 Subject: [PATCH 6/6] fix citation in header --- brainrender_napari/brainrender_manager_widget.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/brainrender_napari/brainrender_manager_widget.py b/brainrender_napari/brainrender_manager_widget.py index 22480af..1391533 100644 --- a/brainrender_napari/brainrender_manager_widget.py +++ b/brainrender_napari/brainrender_manager_widget.py @@ -34,10 +34,9 @@ def __init__(self, napari_viewer: Viewer): "brainrender", "Atlas management", tutorial_file_name="manage-atlas-napari.html", - citation_doi="https://doi.org/10.7554/eLife.65751", + citation_doi="https://doi.org/10.21105/joss.02668", github_repo_name="brainrender-napari", - help_text="For help, hover the cursor over the " - "atlases/regions.", + help_text="For help, hover the cursor over the " "atlases.", ) )