Repository: scalableminds/webknossos-libs

Issue:
Add MagView.get_views_on_disk
[MagView.get_bounding_boxes_on_disk](https://docs.webknossos.org/api/webknossos/dataset/mag_view.html#MagView.get_bounding_boxes_on_disk) is very useful. However, there may be some confusion, because it returns global offsets, even when the `MagView` has its own offset. It would be great to add a new method that returns `View`s directly.

Also, `MagView.get_bounding_boxes_on_disk` doesn't return bboxes but `(offset, size)` pairs.


Discussion:
The method now returns bounding boxes and using global offsets is more staight forward. A small wrapper returning views would still be useful :+1: 

Resolving patch:
diff --git a/webknossos/webknossos/annotation/annotation.py b/webknossos/webknossos/annotation/annotation.py
--- a/webknossos/webknossos/annotation/annotation.py
+++ b/webknossos/webknossos/annotation/annotation.py
@@ -571,8 +571,8 @@ def export_volume_layer_to_dataset(
 
         if largest_segment_id is None:
             max_value = max(
-                best_mag_view.read(absolute_bounding_box=bbox).max()
-                for bbox in best_mag_view.get_bounding_boxes_on_disk()
+                view.read().max()
+                for view in best_mag_view.get_views_on_disk(read_only=True)
             )
             layer.largest_segment_id = int(max_value)
         else:
diff --git a/webknossos/webknossos/dataset/mag_view.py b/webknossos/webknossos/dataset/mag_view.py
--- a/webknossos/webknossos/dataset/mag_view.py
+++ b/webknossos/webknossos/dataset/mag_view.py
@@ -4,7 +4,7 @@
 import warnings
 from argparse import Namespace
 from pathlib import Path
-from typing import TYPE_CHECKING, Generator, Optional, Union
+from typing import TYPE_CHECKING, Iterator, Optional, Union
 from uuid import uuid4
 
 import numpy as np
@@ -227,7 +227,7 @@ def get_view(
 
     def get_bounding_boxes_on_disk(
         self,
-    ) -> Generator[BoundingBox, None, None]:
+    ) -> Iterator[BoundingBox]:
         """
         Returns a Mag(1) bounding box for each file on disk.
 
@@ -242,6 +242,18 @@ def get_bounding_boxes_on_disk(
 
             yield BoundingBox(cube_offset, cube_size).from_mag_to_mag1(self._mag)
 
+    def get_views_on_disk(
+        self,
+        read_only: Optional[bool] = None,
+    ) -> Iterator[View]:
+        """
+        Yields a view for each file on disk, which can be used for efficient parallelization.
+        """
+        for bbox in self.get_bounding_boxes_on_disk():
+            yield self.get_view(
+                absolute_offset=bbox.topleft, size=bbox.size, read_only=read_only
+            )
+
     def compress(
         self,
         target_path: Optional[Union[str, Path]] = None,
diff --git a/webknossos/webknossos/skeleton/__init__.py b/webknossos/webknossos/skeleton/__init__.py
--- a/webknossos/webknossos/skeleton/__init__.py
+++ b/webknossos/webknossos/skeleton/__init__.py
@@ -9,6 +9,7 @@
 
 
 def open_nml(file_path: Union[PathLike, str]) -> Skeleton:
+    """open_nml is deprecated, please use Skeleton.load instead."""
     warnings.warn(
         "[DEPRECATION] open_nml is deprecated, please use Skeleton.load instead."
     )


Test patch: