InsightSoftwareConsortium / InsightSoftwareConsortium/itkwidgets
`ZeroDivisionError` when attempting to open ITK image
- Dominant language
- Python
- Stars
- 624
- Forks
- 83
- PR merge metrics
- No merged PRs in 30d
Description
## Background
Observed zero division error when trying to view 3D ITK image with itkwidgets.view in a Jupyter notebook.
## Output
Cell:
```
itkwidgets.view(average_template_10)
```
Output:
```
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[4], line 1
----> 1 itkwidgets.view(average_template_10)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\itkwidgets\viewer.py:436, in view(data, **kwargs)
322 def view(data=None, **kwargs):
323 """View the image and/or point sets.
324
325 Creates and returns an ImJoy plugin ipywidget to visualize an image, and/or
(...)
434 properties on the object to change the visualization.
435 """
--> 436 viewer = Viewer(data=data, **kwargs)
438 return viewer
File ~\Anaconda3\envs\venv-itk\lib\site-packages\itkwidgets\viewer.py:136, in Viewer.__init__(self, ui_collapsed, rotate, ui, **add_data_kwargs)
132 def __init__(
133 self, ui_collapsed=True, rotate=False, ui="pydata-sphinx", **add_data_kwargs
134 ):
135 input_data = self.input_data(add_data_kwargs)
--> 136 data = self.init_data(input_data)
137 """Create a viewer."""
138 self.viewer_rpc = ViewerRPC(
139 ui_collapsed=ui_collapsed, rotate=rotate, ui=ui, data=data
140 )
File ~\Anaconda3\envs\venv-itk\lib\site-packages\itkwidgets\viewer.py:175, in Viewer.init_data(self, input_data)
173 result = _get_viewer_image(data, label=True)
174 else:
--> 175 result = _get_viewer_image(data, label=False)
176 elif render_type is RenderType.POINT_SET:
177 result = _get_viewer_point_sets(data)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\itkwidgets\integrations\__init__.py:70, in _get_viewer_image(image, label)
68 ngff_image = itk_image_to_ngff_image(image)
69 multiscales = to_multiscales(ngff_image, method=method)
---> 70 to_ngff_zarr(store, multiscales, chunk_store=chunk_store)
71 return store
73 if HAVE_VTK:
File ~\Anaconda3\envs\venv-itk\lib\site-packages\ngff_zarr\to_ngff_zarr.py:61, in to_ngff_zarr(store, multiscales, compute, overwrite, chunk_store, **kwargs)
59 path_group = root.create_group(path)
60 path_group.attrs["_ARRAY_DIMENSIONS"] = image.dims
---> 61 arr = dask.array.to_zarr(
62 arr,
63 store,
64 component=path,
65 overwrite=overwrite,
66 compute=compute,
67 return_stored=True,
68 **kwargs,
69 )
70 arrays.append(arr)
72 zarr.consolidate_metadata(store)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\array\core.py:3687, in to_zarr(arr, url, component, storage_options, overwrite, region, compute, return_stored, **kwargs)
3676 chunks = [c[0] for c in arr.chunks]
3678 z = zarr.create(
3679 shape=arr.shape,
3680 chunks=chunks,
(...)
3685 **kwargs,
3686 )
-> 3687 return arr.store(z, lock=False, compute=compute, return_stored=return_stored)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\array\core.py:1757, in Array.store(self, target, **kwargs)
1755 @wraps(store)
1756 def store(self, target, **kwargs):
-> 1757 r = store([self], [target], **kwargs)
1759 if kwargs.get("return_stored", False):
1760 r = r[0]
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\array\core.py:1218, in store(***failed resolving arguments***)
1216 if compute:
1217 store_dlyds = [Delayed(k, store_dsk, layer=k[0]) for k in map_keys]
-> 1218 store_dlyds = persist(*store_dlyds, **kwargs)
1219 store_dsk_2 = HighLevelGraph.merge(*[e.dask for e in store_dlyds])
1220 load_store_dsk = retrieve_from_ooc(map_keys, store_dsk, store_dsk_2)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\base.py:899, in persist(traverse, optimize_graph, scheduler, *args, **kwargs)
896 keys.extend(a_keys)
897 postpersists.append((rebuild, a_keys, state))
--> 899 results = schedule(dsk, keys, **kwargs)
900 d = dict(zip(keys, results))
901 results2 = [r({k: d[k] for k in ks}, *s) for r, ks, s in postpersists]
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\threaded.py:89, in get(dsk, keys, cache, num_workers, pool, **kwargs)
86 elif isinstance(pool, multiprocessing.pool.Pool):
87 pool = MultiprocessingPoolExecutor(pool)
---> 89 results = get_async(
90 pool.submit,
91 pool._max_workers,
92 dsk,
93 keys,
94 cache=cache,
95 get_id=_thread_get_id,
96 pack_exception=pack_exception,
97 **kwargs,
98 )
100 # Cleanup pools associated to dead threads
101 with pools_lock:
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\local.py:511, in get_async(submit, num_workers, dsk, result, cache, get_id, rerun_exceptions_locally, pack_exception, raise_exception, callbacks, dumps, loads, chunksize, **kwargs)
509 _execute_task(task, data) # Re-execute locally
510 else:
--> 511 raise_exception(exc, tb)
512 res, worker_id = loads(res_info)
513 state["cache"][key] = res
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\local.py:319, in reraise(exc, tb)
317 if exc.__traceback__ is not tb:
318 raise exc.with_traceback(tb)
--> 319 raise exc
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\local.py:224, in execute_task(key, task_info, dumps, loads, get_id, pack_exception)
222 try:
223 task, data = loads(task_info)
--> 224 result = _execute_task(task, data)
225 id = get_id()
226 result = dumps((result, id))
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\core.py:119, in _execute_task(arg, cache, dsk)
115 func, args = arg[0], arg[1:]
116 # Note: Don't assign the subtask results to a variable. numpy detects
117 # temporaries by their reference count and can execute certain
118 # operations in-place.
--> 119 return func(*(_execute_task(a, cache) for a in args))
120 elif not ishashable(arg):
121 return arg
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\array\core.py:4356, in store_chunk(x, out, index, lock, return_stored)
4353 def store_chunk(
4354 x: ArrayLike, out: ArrayLike, index: slice, lock: Any, return_stored: bool
4355 ):
-> 4356 return load_store_chunk(x, out, index, lock, return_stored, False)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\dask\array\core.py:4338, in load_store_chunk(x, out, index, lock, return_stored, load_stored)
4336 if x is not None:
4337 if is_arraylike(x):
-> 4338 out[index] = x
4339 else:
4340 out[index] = np.asanyarray(x)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\zarr\core.py:1353, in Array.__setitem__(self, selection, value)
1351 self.vindex[selection] = value
1352 else:
-> 1353 self.set_basic_selection(pure_selection, value, fields=fields)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\zarr\core.py:1448, in Array.set_basic_selection(self, selection, value, fields)
1446 return self._set_basic_selection_zd(selection, value, fields=fields)
1447 else:
-> 1448 return self._set_basic_selection_nd(selection, value, fields=fields)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\zarr\core.py:1746, in Array._set_basic_selection_nd(self, selection, value, fields)
1742 def _set_basic_selection_nd(self, selection, value, fields=None):
1743 # implementation of __setitem__ for array with at least one dimension
1744
1745 # setup indexer
-> 1746 indexer = BasicIndexer(selection, self)
1748 self._set_selection(indexer, value, fields=fields)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\zarr\indexing.py:342, in BasicIndexer.__init__(self, selection, array)
339 dim_indexer = IntDimIndexer(dim_sel, dim_len, dim_chunk_len)
341 elif is_slice(dim_sel):
--> 342 dim_indexer = SliceDimIndexer(dim_sel, dim_len, dim_chunk_len)
344 else:
345 raise IndexError('unsupported selection item for basic indexing; '
346 'expected integer or slice, got {!r}'
347 .format(type(dim_sel)))
File ~\Anaconda3\envs\venv-itk\lib\site-packages\zarr\indexing.py:176, in SliceDimIndexer.__init__(self, dim_sel, dim_len, dim_chunk_len)
174 self.dim_chunk_len = dim_chunk_len
175 self.nitems = max(0, ceildiv((self.stop - self.start), self.step))
--> 176 self.nchunks = ceildiv(self.dim_len, self.dim_chunk_len)
File ~\Anaconda3\envs\venv-itk\lib\site-packages\zarr\indexing.py:160, in ceildiv(a, b)
159 def ceildiv(a, b):
--> 160 return math.ceil(a / b)
ZeroDivisionError: division by zero
```
## Additional Information
The error does not appear and viewing does succeed when the image is cropped to a smaller size, i.e. 400x400x1000.
Image information printout:
```
Image (00000221E1D0D4E0)
RTTI typeinfo: class itk::Image
Reference Count: 1
Modified Time: 427
Debug: Off
Object Name:
Observers:
none
Source: (none)
Source output name: (none)
Release Data: Off
Data Released: False
Global Release Data: Off
PipelineMTime: 237
UpdateMTime: 426
RealTimeStamp: 0 seconds
LargestPossibleRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [1320, 800, 1140]
BufferedRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [1320, 800, 1140]
RequestedRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [1320, 800, 1140]
Spacing: [10, 10, 10]
Origin: [0, 0, 0]
Direction:
1 0 0
0 1 0
0 0 1
IndexToPointMatrix:
10 0 0
0 10 0
0 0 10
PointToIndexMatrix:
0.1 0 0
0 0.1 0
0 0 0.1
Inverse Direction:
1 0 0
0 1 0
0 0 1
PixelContainer:
ImportImageContainer (00000221E5B729E0)
RTTI typeinfo: class itk::ImportImageContainer
Reference Count: 1
Modified Time: 423
Debug: Off
Object Name:
Observers:
none
Pointer: 00000221E8CF2040
Container manages memory: true
Size: 1203840000
Capacity: 1203840000
```
## Steps to reproduce
Download CCFv3 `average_template_10.nrrd`: http://download.alleninstitute.org/informatics-archive/current-release/mouse_ccf/average_template/
Load and view:
```
> import itk
> import itkwidgets
> image = itk.imread('path/to/average_template_10.nrrd')
> itkwidgets.view(image)
```
## Platform Information
Windows 10
```sh
> python -m pip list | grep itk
itk 5.3.0
itk-core 5.3.0
itk-elastix 0.15.0
itk-filtering 5.3.0
itk-io 5.3.0
itk-numerics 5.3.0
itk-registration 5.3.0
itk-segmentation 5.3.0
itkwasm 1.0b1
itkwidgets 1.0a21
> python -m pip list | grep jupyter
imjoy-jupyter-extension 0.3.0
imjoy-jupyterlab-extension 0.1.13
jupyter-black 0.3.3
jupyter-book 0.13.1
jupyter-cache 0.4.3
jupyter_client 7.4.7
jupyter_core 5.1.0
jupyter-server 1.23.3
jupyter-server-proxy-windows 1.5.1
jupyter-sphinx 0.3.2
jupyterlab 3.5.0
jupyterlab-pygments 0.2.2
jupyterlab_server 2.16.3
jupyterlab-widgets 3.0.3
sphinx-jupyterbook-latex 0.4.7
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.