Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add correct enablement kwarg to Split Stack action, Convert data type submenu and Projections submenu #5437

Merged
merged 7 commits into from Jan 8, 2023

Conversation

dalthviz
Copy link
Member

Description

Fix layer context menu enable/disable state for the Split Stack action, Convert data type submenu and Projections submenu

Before:

ctx_menu_before

After:

ctx_menu_after

Type of change

  • Bug-fix (non-breaking change which fixes an issue)

References

closes #5418

How has this been tested?

  • all tests pass with my change
  • I check if my changes works with both PySide and PyQt backends
    as there are small differences between the two Qt bindings.

Final checklist:

  • My PR is the minimum possible work for the desired functionality
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • If I included new strings, I have used trans. to make them localizable.
    For more information see our translations guide.

@dalthviz dalthviz self-assigned this Dec 22, 2022
@codecov
Copy link

codecov bot commented Dec 23, 2022

Codecov Report

Merging #5437 (e851188) into main (aebf02b) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##             main    #5437   +/-   ##
=======================================
  Coverage   89.23%   89.23%           
=======================================
  Files         599      599           
  Lines       50884    50887    +3     
=======================================
+ Hits        45405    45409    +4     
+ Misses       5479     5478    -1     
Impacted Files Coverage Δ
napari/_app_model/actions/_layer_actions.py 100.00% <ø> (ø)
napari/_app_model/_submenus.py 100.00% <100.00%> (ø)
napari/_app_model/context/_layerlist_context.py 92.77% <100.00%> (+1.63%) ⬆️
napari/components/experimental/chunk/_pool.py 85.71% <0.00%> (-7.94%) ⬇️
napari/_qt/dialogs/qt_package_installer.py 81.67% <0.00%> (+0.39%) ⬆️
napari/utils/theme.py 92.85% <0.00%> (+0.59%) ⬆️
napari/utils/info.py 81.44% <0.00%> (+1.03%) ⬆️
napari/_qt/__init__.py 56.66% <0.00%> (+6.66%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Copy link
Member

@psobolewskiPhD psobolewskiPhD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing this I noticed we error with projections of RGB images (below).
Let's fix that here too by not enabling projections for 2D RGB images (which have shape 3)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/Dev/miniforge3/envs/napari-dev/lib/python3.10/site-packages/vispy/app/backends/_qt.py:903, in CanvasBackendDesktop.paintGL(self=<vispy.app.backends._qt.CanvasBackendDesktop object>)
    901 # (0, 0, self.width(), self.height()))
    902 self._vispy_canvas.set_current()
--> 903 self._vispy_canvas.events.draw(region=None)
        self._vispy_canvas = <VispyCanvas (PyQt5) at 0x283ce5090>
        self._vispy_canvas.events.draw = <vispy.util.event.EventEmitter object at 0x283cf85e0>
        self = <vispy.app.backends._qt.CanvasBackendDesktop object at 0x283cde5f0>
        self._vispy_canvas.events = <vispy.util.event.EmitterGroup object at 0x283cf8580>
    905 # Clear the alpha channel with QOpenGLWidget (Qt >= 5.4), otherwise the
    906 # window is translucent behind non-opaque objects.
    907 # Reference:  MRtrix3/mrtrix3#266
    908 if QT5_NEW_API or PYSIDE6_API or PYQT6_API:

File ~/Dev/miniforge3/envs/napari-dev/lib/python3.10/site-packages/vispy/util/event.py:453, in EventEmitter.__call__(self=<vispy.util.event.EventEmitter object>, *args=(), **kwargs={'region': None})
    450 if self._emitting > 1:
    451     raise RuntimeError('EventEmitter loop detected!')
--> 453 self._invoke_callback(cb, event)
        event = <DrawEvent blocked=False handled=False native=None region=None source=None sources=[] type=draw>
        self = <vispy.util.event.EventEmitter object at 0x283cf85e0>
        cb = <bound method QtViewer.on_draw of <napari._qt.qt_viewer.QtViewer object at 0x283caae60>>
    454 if event.blocked:
    455     break

File ~/Dev/miniforge3/envs/napari-dev/lib/python3.10/site-packages/vispy/util/event.py:471, in EventEmitter._invoke_callback(self=<vispy.util.event.EventEmitter object>, cb=<bound method QtViewer.on_draw of <napari._qt.qt_viewer.QtViewer object>>, event=<DrawEvent blocked=False handled=False native=None region=None source=None sources=[] type=draw>)
    469     cb(event)
    470 except Exception:
--> 471     _handle_exception(self.ignore_callback_errors,
        self = <vispy.util.event.EventEmitter object at 0x283cf85e0>
        cb = <bound method QtViewer.on_draw of <napari._qt.qt_viewer.QtViewer object at 0x283caae60>>
        event = <DrawEvent blocked=False handled=False native=None region=None source=None sources=[] type=draw>
        (cb, event) = (<bound method QtViewer.on_draw of <napari._qt.qt_viewer.QtViewer object at 0x283caae60>>, <DrawEvent blocked=False handled=False native=None region=None source=None sources=[] type=draw>)
    472                       self.print_callback_errors,
    473                       self, cb_event=(cb, event))

File ~/Dev/miniforge3/envs/napari-dev/lib/python3.10/site-packages/vispy/util/event.py:469, in EventEmitter._invoke_callback(self=<vispy.util.event.EventEmitter object>, cb=<bound method QtViewer.on_draw of <napari._qt.qt_viewer.QtViewer object>>, event=<DrawEvent blocked=False handled=False native=None region=None source=None sources=[] type=draw>)
    467 def _invoke_callback(self, cb, event):
    468     try:
--> 469         cb(event)
        cb = <bound method QtViewer.on_draw of <napari._qt.qt_viewer.QtViewer object at 0x283caae60>>
        event = <DrawEvent blocked=False handled=False native=None region=None source=None sources=[] type=draw>
    470     except Exception:
    471         _handle_exception(self.ignore_callback_errors,
    472                           self.print_callback_errors,
    473                           self, cb_event=(cb, event))

File ~/Dev/napari/napari/_qt/qt_viewer.py:1119, in QtViewer.on_draw(self=<napari._qt.qt_viewer.QtViewer object>, event=<DrawEvent blocked=False handled=False native=None region=None source=None sources=[] type=draw>)
   1117 else:
   1118     displayed_axes = self.viewer.dims.displayed[-nd:]
-> 1119 layer._update_draw(
        layer = <Image layer 'astronaut mean-proj' at 0x299407100>
        self = <napari._qt.qt_viewer.QtViewer object at 0x283caae60>
        self.viewer = Viewer(axes=AxesOverlay(visible=False, opacity=1.0, order=1000000, labels=True, colored=True, dashed=False, arrows=True), camera=Camera(center=(0.0, 255.5, 255.5), zoom=1.5159179687499997, angles=(0.0, 0.0, 90.0), perspective=0.0, interactive=True), cursor=Cursor(position=(289.80263756167017, 25.60629333267907), scaled=True, size=1, style=<CursorStyle.STANDARD: 'standard'>), dims=Dims(ndim=2, ndisplay=2, last_used=0, range=((0.0, 512.0, 1.0), (0.0, 512.0, 1.0)), current_step=(256, 256), order=(0, 1), axis_labels=('0', '1')), grid=GridCanvas(stride=1, shape=(-1, -1), enabled=False), layers=[<Image layer 'astronaut' at 0x16b315b70>, <Image layer 'astronaut mean-proj' at 0x299407100>], scale_bar=ScaleBarOverlay(visible=False, opacity=1.0, order=1000000, position=<CanvasPosition.BOTTOM_RIGHT: 'bottom_right'>, colored=False, color=<class 'numpy.ndarray'> (4,) float32, ticks=True, font_size=10.0, box=False, box_color=<class 'numpy.ndarray'> (4,) float32, unit=None), text_overlay=TextOverlay(visible=False, opacity=1.0, order=1000000, position=<CanvasPosition.BOTTOM_RIGHT: 'bottom_right'>, color=<class 'numpy.ndarray'> (4,) float32, font_size=10.0, text=''), overlays=Overlays(interaction_box=InteractionBox(points=None, show=False, show_handle=False, show_vertices=False, selection_box_drag=None, selection_box_final=None, transform_start=<napari.utils.transforms.transforms.Affine object at 0x16f0fada0>, transform_drag=<napari.utils.transforms.transforms.Affine object at 0x16f0fae00>, transform_final=<napari.utils.transforms.transforms.Affine object at 0x16f0fae60>, transform=<napari.utils.transforms.transforms.Affine object at 0x16f0faec0>, allow_new_selection=True, selected_vertex=None)), help='`minimum` blending mode works best with inverted colormaps with a white background.', status='', tooltip=Tooltip(visible=False, text=''), theme='system', title='napari', mouse_over_canvas=False, mouse_move_callbacks=[<function InteractionBoxMouseBindings.initialize_mouse_events.<locals>.mouse_move at 0x284db8e50>], mouse_drag_callbacks=[<function InteractionBoxMouseBindings.initialize_mouse_events.<locals>.mouse_drag at 0x284db8d30>], mouse_double_click_callbacks=[], mouse_wheel_callbacks=[<function dims_scroll at 0x16e7b8790>], _persisted_mouse_event={}, _mouse_drag_gen={}, _mouse_wheel_gen={}, keymap={<app_model.types._keys._keybindings.KeyBinding object at 0x284d8e380>: <function InteractionBoxMouseBindings.initialize_key_events.<locals>.hold_to_lock_aspect_ratio at 0x284db9b40>, <app_model.types._keys._keybindings.KeyBinding object at 0x16d7181f0>: <function InteractionBoxMouseBindings._reset_active_layer_affine at 0x284cc6dd0>, <app_model.types._keys._keybindings.KeyBinding object at 0x16d718280>: <function InteractionBoxMouseBindings._transform_active_layer at 0x284cc7250>})
        self.viewer.camera.zoom = 1.5159179687499997
        self.viewer.camera = Camera(center=(0.0, 255.5, 255.5), zoom=1.5159179687499997, angles=(0.0, 0.0, 90.0), perspective=0.0, interactive=True)
        canvas_corners_world = <class 'numpy.ndarray'> (2, 2) float64
        displayed_axes = (0, 1)
        self.canvas = <VispyCanvas (PyQt5) at 0x283ce5090>
   1120     scale_factor=1 / self.viewer.camera.zoom,
   1121     corner_pixels_displayed=canvas_corners_world[
   1122         :, displayed_axes
   1123     ],
   1124     shape_threshold=self.canvas.size,
   1125 )

File ~/Dev/napari/napari/layers/base/base.py:1508, in Layer._update_draw(self=<Image layer 'astronaut mean-proj'>, scale_factor=0.6596663016169556, corner_pixels_displayed=<class 'numpy.ndarray'> (2, 2) float64, shape_threshold=(817, 840))
   1504 all_corners = list(itertools.product(*corner_pixels_displayed.T))
   1505 # Note that we ignore the first transform which is tile2data
   1506 data_corners = (
   1507     self._transforms[1:]
-> 1508     .simplified.set_slice(displayed_axes)
        self = <Image layer 'astronaut mean-proj' at 0x299407100>
        self._transforms = [<napari.utils.transforms.transforms.Affine object at 0x29941fa30>, <napari.utils.transforms.transforms.CompositeAffine object at 0x29941f910>, <napari.utils.transforms.transforms.Affine object at 0x29941fa00>, <napari.utils.transforms.transforms.Affine object at 0x29941f9d0>]
        displayed_axes = [0, 1]
        all_corners = [(-21.55984700751987, -13.973683519336621), (-21.55984700751987, 524.9736679489437), (532.5598289206996, -13.973683519336621), (532.5598289206996, 524.9736679489437)]
   1509     .inverse(all_corners)
   1510 )
   1512 # find the maximal data-axis-aligned bounding box containing all four
   1513 # canvas corners and round them to ints
   1514 data_bbox = np.stack(
   1515     [np.min(data_corners, axis=0), np.max(data_corners, axis=0)]
   1516 )

File ~/Dev/napari/napari/utils/transforms/transforms.py:151, in TransformChain.simplified(self=[<napari.utils.transforms.transforms.CompositeAf...nsforms.transforms.Affine object at 0x29941f9d0>])
    149     return self[0]
    150 else:
--> 151     return tz.pipe(self[0], *[tf.compose for tf in self[1:]])
        self = [<napari.utils.transforms.transforms.CompositeAffine object at 0x29941f910>, <napari.utils.transforms.transforms.Affine object at 0x29941fa00>, <napari.utils.transforms.transforms.Affine object at 0x29941f9d0>]
        tz = <module 'toolz' from '/Users/piotrsobolewski/Dev/miniforge3/envs/napari-dev/lib/python3.10/site-packages/toolz/__init__.py'>

File ~/Dev/miniforge3/envs/napari-dev/lib/python3.10/site-packages/toolz/functoolz.py:628, in pipe(data=<napari.utils.transforms.transforms.Affine object>, *funcs=(<bound method Affine.compose of <napari.utils.transforms.transforms.Affine object>>, <bound method Affine.compose of <napari.utils.transforms.transforms.Affine object>>))
    608 """ Pipe a value through a sequence of functions
    609 
    610 I.e. ``pipe(data, f, g, h)`` is equivalent to ``h(g(f(data)))``
   (...)
    625     thread_last
    626 """
    627 for func in funcs:
--> 628     data = func(data)
        func = <bound method Affine.compose of <napari.utils.transforms.transforms.Affine object at 0x29941f9d0>>
        data = <napari.utils.transforms.transforms.Affine object at 0x29baa3b80>
    629 return data

File ~/Dev/napari/napari/utils/transforms/transforms.py:553, in Affine.compose(self=<napari.utils.transforms.transforms.Affine object>, transform=<napari.utils.transforms.transforms.Affine object>)
    551 if not isinstance(transform, Affine):
    552     return super().compose(transform)
--> 553 affine_matrix = self.affine_matrix @ transform.affine_matrix
        transform = <napari.utils.transforms.transforms.Affine object at 0x29baa3b80>
        self = <napari.utils.transforms.transforms.Affine object at 0x29941f9d0>
    554 return Affine(affine_matrix=affine_matrix)

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 3 is different from 2)

dalthviz and others added 3 commits December 26, 2022 11:55
Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
@psobolewskiPhD psobolewskiPhD merged commit 9104fd3 into napari:main Jan 8, 2023
kne42 added a commit to kne42/napari that referenced this pull request Jan 9, 2023
* main:
  Bugfix: Ensure layer._fixed_vertex is set when rotating (napari#5449)
  Bugfix: Fix test_get_system_theme test for `name` to `id` change (napari#5456)
  Add correct `enablement` kwarg to `Split Stack` action, `Convert data type` submenu and `Projections` submenu (napari#5437)
  Add error color to themes and change application close/exit dialogs (napari#5442)
  Add auto canceling previous test after a new PR commit (napari#5453)
  Fix theme id reference to get image for 'success_label' style (napari#5447)
  Decouple changing viewer.theme from changing theme settings/preferences (napari#5143)
  [pre-commit.ci] pre-commit autoupdate (napari#5422)
  Configure `fail_on_no_env` for `tox-gh-actions` (napari#5408)
melissawm pushed a commit to melissawm/napari that referenced this pull request Jan 11, 2023
… type` submenu and `Projections` submenu (napari#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
@Czaki Czaki mentioned this pull request Jun 7, 2023
@Czaki Czaki added this to the 0.4.18 milestone Jun 16, 2023
Czaki pushed a commit that referenced this pull request Jun 16, 2023
… type` submenu and `Projections` submenu (#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 17, 2023
… type` submenu and `Projections` submenu (#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 18, 2023
… type` submenu and `Projections` submenu (#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 19, 2023
… type` submenu and `Projections` submenu (#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 21, 2023
… type` submenu and `Projections` submenu (#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 21, 2023
… type` submenu and `Projections` submenu (#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 21, 2023
… type` submenu and `Projections` submenu (#5437)

* Add correct enablement kwarg to 'Split Stack' action, 'Convert data type' submenu and 'Projections' submenu

* Check _active_ndim is valid

* Apply suggestions from code review

Handle case for 2D RGB images

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check _active_ndims is not None

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Minor bug: in the layer contextual menu, Split Stack is not disabled for single-channel 2D images.
4 participants