question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Crash while thumbnail generation when setting `layer.data` (in case of label layers)

See original GitHub issue

🐛 Bug

I’m just trying to port napari-pyclesperanto-prototype (a napari plugin) from napari 0.4.5 to 0.4.7. When using the assistant, napari crashes inside a routine that draws thumbnails for the layer list. When surrounding the crash with a try-except-block, more things go wrong. Were there major changes in how layer.data and layer.name can be set?

To Reproduce

  • Install the assistant (which brings napari 0.4.5) and afterwards install napari 0.4.7
git clone https://github.com/clesperanto/napari_pyclesperanto_assistant
cd napari_pyclesperanto_assistant
pip install -e .
pip install napari==0.4.7
  • Run the assistant demo:
python docs/demo/start_assistant.py
  • Click on the “Binarize” button on the right. It will try to add a “Label” layer and crash while setting layer.data in this line with this error message:
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\labels\labels.py in _raw_to_displayed(self=, raw=array([[1., 1., 1., ..., 0., 0., 0.],
       [0....   [1., 1., 1., ..., 0., 0., 0.]], dtype=float32))
    704             try:
--> 705                 image = self._all_vals[raw]
        image = undefined
        self._all_vals = array([0.       , 0.1210181])
        raw = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)
    706             except IndexError:

IndexError: arrays used as indices must be of integer (or boolean) type

During handling of the above exception, another exception occurred:

IndexError                                Traceback (most recent call last)
C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\widgets\_bases.py in (*x=(,))
    429         self.changed = EventEmitter(source=self, type="changed")
    430         self._widget._mgui_bind_change_callback(
--> 431             lambda *x: self.changed(value=x[0] if x else None)
        x = (,)
        global self.changed = undefined
        global value = undefined
    432         )
    433 

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\events.py in __call__(self=, *args=(), **kwargs={'value': })
    601                     continue
    602 
--> 603                 self._invoke_callback(cb, event)
        self._invoke_callback = >
        cb = . at 0x0000022CC45800D0>
        event = 
    604                 if event.blocked:
    605                     break

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\events.py in _invoke_callback(self=, cb=.>, event=)
    619             cb(event)
    620         except Exception:
--> 621             _handle_exception(
        global _handle_exception = 
        self.ignore_callback_errors = False
        self.print_callback_errors = 'reminders'
        self = 
        global cb_event = undefined
        cb = . at 0x0000022CC45800D0>
        event = 
    622                 self.ignore_callback_errors,
    623                 self.print_callback_errors,

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\events.py in _invoke_callback(self=, cb=.>, event=)
    617     def _invoke_callback(self, cb, event):
    618         try:
--> 619             cb(event)
        cb = . at 0x0000022CC45800D0>
        event = 
    620         except Exception:
    621             _handle_exception(

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\widgets\_bases.py in (x=)
   1040         """Insert widget at ``key``."""
   1041         if isinstance(widget, ValueWidget):
-> 1042             widget.changed.connect(lambda x: self.changed(value=self))
        global widget.changed.connect = undefined
        x = 
        global self.changed = undefined
        global value = undefined
        global self = undefined
   1043         _widget = widget
   1044 

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\events.py in __call__(self=, *args=(), **kwargs={'value': })
    601                     continue
    602 
--> 603                 self._invoke_callback(cb, event)
        self._invoke_callback = >
        cb = . at 0x0000022CC4589790>
        event = 
    604                 if event.blocked:
    605                     break

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\events.py in _invoke_callback(self=, cb=.>, event=)
    619             cb(event)
    620         except Exception:
--> 621             _handle_exception(
        global _handle_exception = 
        self.ignore_callback_errors = False
        self.print_callback_errors = 'reminders'
        self = 
        global cb_event = undefined
        cb = . at 0x0000022CC4589790>
        event = 
    622                 self.ignore_callback_errors,
    623                 self.print_callback_errors,

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\events.py in _invoke_callback(self=, cb=.>, event=)
    617     def _invoke_callback(self, cb, event):
    618         try:
--> 619             cb(event)
        cb = . at 0x0000022CC4589790>
        event = 
    620         except Exception:
    621             _handle_exception(

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\function_gui.py in (e=)
    106         self._auto_call = auto_call
    107         if auto_call:
--> 108             self.changed.connect(lambda e: self.__call__())
        global self.changed.connect = undefined
        e = 
        global self.__call__ = undefined
    109 
    110         if show:

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\magicgui\function_gui.py in __call__(self=, *args=(), **kwargs={})
    171         bound.apply_defaults()
    172 
--> 173         value = self._function(*bound.args, **bound.kwargs)
        value = undefined
        self._function = 
        bound.args = (, 'threshold_otsu', 1, 1, 0)
        bound.kwargs = {}
    174         self._call_count += 1
    175         if self._result_widget is not None:

c:\structure\code\napari_pyclesperanto_assistant\napari_pyclesperanto_assistant\_operations\_operations.py in binarize(input1=, operation_name='threshold_otsu', radius_x=1, radius_y=1, radius_z=0)
    136             binarize.self.viewer.add_labels(output, translate=input1.translate)
    137         else:
--> 138             binarize.self.layer.data = output
        global binarize.self.layer.data = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)
        output = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)
    139             binarize.self.layer.contrast_limits = (0, 1)
    140             binarize.self.layer.name = "Result of " + operation.__name__

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\image\image.py in data(self=, data=array([[1., 1., 1., ..., 0., 0., 0.],
       [0....   [1., 1., 1., ..., 0., 0., 0.]], dtype=float32))
    333     def data(self, data):
    334         self._data = data
--> 335         self._update_dims()
        self._update_dims = >
    336         self.events.data(value=self.data)
    337         self._set_editable()

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\base\base.py in _update_dims(self=, event=None)
    543         self._ndim = ndim
    544 
--> 545         self.refresh()
        self.refresh = >
    546 
    547     @property

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\base\base.py in refresh(self=, event=None)
    927         """Refresh all layer data based on current view slice."""
    928         if self.visible:
--> 929             self.set_view_slice()
        self.set_view_slice = >
    930             self.events.set_data()
    931             self._update_thumbnail()

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\base\base.py in set_view_slice(self=)
    791     def set_view_slice(self):
    792         with self.dask_optimized_slicing():
--> 793             self._set_view_slice()
        self._set_view_slice = >
    794 
    795     @abstractmethod

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\image\image.py in _set_view_slice(self=)
    588         # Load our images, might be sync or async.
    589         data = SliceDataClass(self, image_indices, image, thumbnail_source)
--> 590         self._load_slice(data)
        self._load_slice = >
        data = 
    591 
    592     def _load_slice(self, data: SliceDataClass):

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\image\image.py in _load_slice(self=, data=)
    599         if self._slice.load(data):
    600             # The load was synchronous.
--> 601             self._on_data_loaded(data, sync=True)
        self._on_data_loaded = >
        data = 
        global sync = undefined
    602         else:
    603             # The load will be asynchronous. Signal that our self.loaded

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\image\image.py in _on_data_loaded(self=, data=, sync=True)
    623 
    624         # Pass the loaded data to the slice.
--> 625         if not self._slice.on_loaded(data):
        self._slice.on_loaded = >
        data = 
    626             # Slice rejected it, was it for the wrong indices?
    627             return

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\image\_image_slice.py in on_loaded(self=, data=)
    136 
    137         # Display the newly loaded data.
--> 138         self._set_raw_images(data.image, data.thumbnail_source)
        self._set_raw_images = >
        data.image = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)
        data.thumbnail_source = None
    139         self.loaded = True
    140         return True  # data was used.

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\image\_image_slice.py in _set_raw_images(self=, image=array([[1., 1., 1., ..., 0., 0., 0.],
       [0....   [1., 1., 1., ..., 0., 0., 0.]], dtype=float32), thumbnail_source=array([[1., 1., 1., ..., 0., 0., 0.],
       [0....   [1., 1., 1., ..., 0., 0., 0.]], dtype=float32))
     94             image = np.clip(image, 0, 1)
     95             thumbnail_source = np.clip(thumbnail_source, 0, 1)
---> 96         self.image.raw = image
        self.image.raw = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)
        image = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)
     97 
     98         # save a computation of view image if thumbnail and image is equal

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\image\_image_view.py in raw(self=, raw_image=array([[1., 1., 1., ..., 0., 0., 0.],
       [0....   [1., 1., 1., ..., 0., 0., 0.]], dtype=float32))
     71 
     72         # Update the view image based on this new raw image.
---> 73         self._view = self.image_converter(raw_image)
        self._view = array([[0.]])
        self.image_converter = >
        raw_image = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)

C:\Programs\miniconda3\envs\beetlesafari\lib\site-packages\napari\layers\labels\labels.py in _raw_to_displayed(self=, raw=array([[1., 1., 1., ..., 0., 0., 0.],
       [0....   [1., 1., 1., ..., 0., 0., 0.]], dtype=float32))
    710                 )
    711                 self._all_vals[0] = 0
--> 712                 image = self._all_vals[raw]
        image = undefined
        self._all_vals = array([0.       , 0.1210181])
        raw = array([[1., 1., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.],
       [1., 1., 1., ..., 0., 0., 0.]], dtype=float32)
    713         elif (
    714             self.show_selected_label

IndexError: arrays used as indices must be of integer (or boolean) type

Expected behavior

It should not crash when layer.data is set.

Environment

  • Please copy and paste the information at napari info option in help menubar here:
napari: 0.4.7
Platform: Windows-10-10.0.19041-SP0
Python: 3.8.8 (default, Feb 24 2021, 15:54:32) [MSC v.1928 64 bit (AMD64)]
Qt: 5.15.2
PyQt5: 5.15.2
NumPy: 1.19.2
SciPy: 1.6.1
Dask: 2021.03.0
VisPy: 0.6.6

OpenGL:
- GL version: 4.6.0 - Build 27.20.100.8681
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 1920x1080, scale 1.0

Plugins:
- clEsperanto: 0.7.3
- console: 0.0.2
- svg: 0.1.4
  • Any other relevant information:

Additional context

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
jnicommented, Mar 31, 2021

But, to clarify: we should raise a more informative error message, not just let things crash the way they do now.

2reactions
jnicommented, Mar 31, 2021

tbh I think we should raise, not warn. Labels should be specified as integers, maybe bools. Automatic float to int conversion is lossy in NumPy by default:

In [1]: import numpy as np

In [2]: np.array([0.2, 0.5, 0.9, 1.1]).astype(int)
Out[2]: array([0, 0, 0, 1])

In the future, when we move the color hashing to OpenGL, we can start using .view since we will be doing that both ways, we can avoid lots of copies. =)

In [3]: np.array([0.2, 0.5, 0.9, 1.1]).view(int)
Out[3]:
array([4596373779694328218, 4602678819172646912, 4606281698874543309,
       4607632778762754458])
Read more comments on GitHub >

github_iconTop Results From Across the Web

Problem: Label tool crashes ArcMap - Esri Support
Using the Label tool, from the Drawing toolbar, to label features for a layer that has a join (Layer Properties Joins & Relates...
Read more >
Fixed issues in prior versions of Photoshop - Adobe Support
(Win) A crash occurs when using the Eyedropper tool to draw on an image without the sky after clicking the sky preset thumbnail...
Read more >
Django sorl thumbnail Crash - Lots of Large images
When ever I have lots of large images, like 800x650 etc in a template, Django just crashes. It works on my Mac locally...
Read more >
Acorn Release Notes - Flying Meat Software
New "Auto Enhance" item under the Layer menu for bitmap layers. ... Fixed a problem where Acorn was crashing with certain images on...
Read more >
Unreal Engine 5.1 Release Notes
World Partition Data Layer Improvements. Data Layers is a system designed to conditionally load and unload your world data by toggling data layers...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found