Ejemplo n.º 1
0
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super( DvidDataSelectionBrowser, self ).__init__(*args, **kwargs)

        self._subvol_widget = SubregionRoiWidget( parent=self )

        subvol_layout = QVBoxLayout()
        subvol_layout.addWidget( self._subvol_widget )
        group_title = "Restrict to subvolume (Right-click a volume name above to auto-initialize these subvolume parameters.)"
        subvol_groupbox = QGroupBox(group_title, parent=self)
        subvol_groupbox.setCheckable(True)
        subvol_groupbox.setChecked(False)
        subvol_groupbox.setEnabled(False)
        subvol_groupbox.toggled.connect( self._update_status )
        subvol_groupbox.setLayout( subvol_layout )
        subvol_groupbox.setFixedHeight( 200 )
        subvol_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Minimum )
        self._subvol_groupbox = subvol_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget( 3, subvol_groupbox )

        # Special right-click behavior.
        self._repo_treewidget.viewport().installEventFilter(self)
Ejemplo n.º 2
0
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super(DvidDataSelectionBrowser, self).__init__(*args, **kwargs)

        self._subvol_widget = SubregionRoiWidget(parent=self)

        subvol_layout = QVBoxLayout()
        subvol_layout.addWidget(self._subvol_widget)
        group_title = (
            "Restrict to subvolume (Right-click a volume name above to auto-initialize these subvolume parameters.)"
        )
        subvol_groupbox = QGroupBox(group_title, parent=self)
        subvol_groupbox.setCheckable(True)
        subvol_groupbox.setChecked(False)
        subvol_groupbox.setEnabled(False)
        subvol_groupbox.toggled.connect(self._update_status)
        subvol_groupbox.setLayout(subvol_layout)
        subvol_groupbox.setFixedHeight(200)
        subvol_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        self._subvol_groupbox = subvol_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget(3, subvol_groupbox)

        # Special right-click behavior.
        self._repo_treewidget.viewport().installEventFilter(self)
Ejemplo n.º 3
0
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super( DvidDataSelectionBrowser, self ).__init__(*args, **kwargs)

        self._roi_widget = SubregionRoiWidget( parent=self )

        roi_layout = QVBoxLayout()
        roi_layout.addWidget( self._roi_widget )
        roi_groupbox = QGroupBox("Specify Region of Interest", parent=self)
        roi_groupbox.setCheckable(True)
        roi_groupbox.setChecked(False)
        roi_groupbox.setEnabled(False)
        roi_groupbox.toggled.connect( self._update_display )
        roi_groupbox.setLayout( roi_layout )
        roi_groupbox.setFixedHeight( 200 )
        roi_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Minimum )
        self._roi_groupbox = roi_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget( 3, roi_groupbox )
Ejemplo n.º 4
0
class DvidDataSelectionBrowser(ContentsBrowser):
    """
    A subclass of the pydvid ContentsBrowser that includes a widget for optional subvolume selection.
    """
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super( DvidDataSelectionBrowser, self ).__init__(*args, **kwargs)

        self._roi_widget = SubregionRoiWidget( parent=self )

        roi_layout = QVBoxLayout()
        roi_layout.addWidget( self._roi_widget )
        roi_groupbox = QGroupBox("Specify Region of Interest", parent=self)
        roi_groupbox.setCheckable(True)
        roi_groupbox.setChecked(False)
        roi_groupbox.setEnabled(False)
        roi_groupbox.toggled.connect( self._update_display )
        roi_groupbox.setLayout( roi_layout )
        roi_groupbox.setFixedHeight( 200 )
        roi_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Minimum )
        self._roi_groupbox = roi_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget( 3, roi_groupbox )

    def get_subvolume_roi(self):
        if self._roi_groupbox.isChecked():
            return self._roi_widget.roi
        return None

    def _update_display(self):
        super( DvidDataSelectionBrowser, self )._update_display()
        hostname, dset_index, dataname, node_uuid = self.get_selection()

        enable_contents = self._datasets_info is not None and dataname != "" and node_uuid != ""
        self._roi_groupbox.setEnabled(enable_contents)

        if dataname == "" or node_uuid == "":
            self._roi_widget.initWithExtents( "", (), (), () )
            return
        
        error_msg = None
        try:
            # Query the server
            connection = httplib.HTTPConnection( hostname )
            raw_metadata = pydvid.voxels.get_metadata( connection, node_uuid, dataname )
            voxels_metadata = pydvid.voxels.VoxelsMetadata( raw_metadata )
        except socket.error as ex:
            error_msg = "Socket Error: {} (Error {})".format( ex.args[1], ex.args[0] )
        except httplib.HTTPException as ex:
            error_msg = "HTTP Error: {}".format( ex.args[0] )

        if error_msg:
            QMessageBox.critical(self, "DVID Error", error_msg)
            self._roi_widget.initWithExtents( "", (), (), () )
            return

        self._roi_widget.initWithExtents( voxels_metadata.axiskeys, voxels_metadata.shape,
                                          voxels_metadata.minindex, voxels_metadata.shape )
Ejemplo n.º 5
0
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super( DvidDataSelectionBrowser, self ).__init__(*args, **kwargs)

        self._roi_widget = SubregionRoiWidget( parent=self )

        roi_layout = QVBoxLayout()
        roi_layout.addWidget( self._roi_widget )
        roi_groupbox = QGroupBox("Specify Region of Interest", parent=self)
        roi_groupbox.setCheckable(True)
        roi_groupbox.setChecked(False)
        roi_groupbox.setEnabled(False)
        roi_groupbox.toggled.connect( self._update_display )
        roi_groupbox.setLayout( roi_layout )
        roi_groupbox.setFixedHeight( 200 )
        roi_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Minimum )
        self._roi_groupbox = roi_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget( 3, roi_groupbox )
Ejemplo n.º 6
0
class DvidDataSelectionBrowser(ContentsBrowser):
    """
    A subclass of the pydvid ContentsBrowser that includes a widget for optional subvolume selection.
    """
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super( DvidDataSelectionBrowser, self ).__init__(*args, **kwargs)

        self._roi_widget = SubregionRoiWidget( parent=self )

        roi_layout = QVBoxLayout()
        roi_layout.addWidget( self._roi_widget )
        roi_groupbox = QGroupBox("Specify Region of Interest", parent=self)
        roi_groupbox.setCheckable(True)
        roi_groupbox.setChecked(False)
        roi_groupbox.setEnabled(False)
        roi_groupbox.toggled.connect( self._update_display )
        roi_groupbox.setLayout( roi_layout )
        roi_groupbox.setFixedHeight( 200 )
        roi_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Minimum )
        self._roi_groupbox = roi_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget( 3, roi_groupbox )

    def get_subvolume_roi(self):
        if self._roi_groupbox.isChecked():
            return self._roi_widget.roi
        return None

    def _update_display(self):
        super( DvidDataSelectionBrowser, self )._update_display()
        hostname, dset_uuid, dataname, node_uuid = self.get_selection()

        enable_contents = self._repos_info is not None and dataname != "" and node_uuid != ""
        self._roi_groupbox.setEnabled(enable_contents)

        if not dataname or not node_uuid:
            self._roi_widget.initWithExtents( "", (), (), () )
            return
        
        error_msg = None
        try:
            # Query the server
            connection = httplib.HTTPConnection( hostname )
            raw_metadata = pydvid.voxels.get_metadata( connection, node_uuid, dataname )
            voxels_metadata = pydvid.voxels.VoxelsMetadata( raw_metadata )
        except socket.error as ex:
            error_msg = "Socket Error: {} (Error {})".format( ex.args[1], ex.args[0] )
        except httplib.HTTPException as ex:
            error_msg = "HTTP Error: {}".format( ex.args[0] )
        except pydvid.errors.DvidHttpError as ex:
            # DVID will return an error if the selected dataset 
            #  isn't a 'voxels' dataset and thus has no voxels metadata
            # In that case, show the error on the console, and don't let the user hit 'okay'.
            log_exception( logger, level=logging.WARN )
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)
            return
        else:
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(True)

        if error_msg:
            QMessageBox.critical(self, "DVID Error", error_msg)
            self._roi_widget.initWithExtents( "", (), (), () )
            return

        self._roi_widget.initWithExtents( voxels_metadata.axiskeys, voxels_metadata.shape,
                                          voxels_metadata.minindex, voxels_metadata.shape )
class DvidDataSelectionBrowser(ContentsBrowser):
    """
    A subclass of the libdvid ContentsBrowser that includes a widget for optional subvolume selection.
    """
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super(DvidDataSelectionBrowser, self).__init__(*args, **kwargs)

        self._roi_widget = SubregionRoiWidget(parent=self)

        roi_layout = QVBoxLayout()
        roi_layout.addWidget(self._roi_widget)
        roi_groupbox = QGroupBox("Specify Region of Interest", parent=self)
        roi_groupbox.setCheckable(True)
        roi_groupbox.setChecked(False)
        roi_groupbox.setEnabled(False)
        roi_groupbox.toggled.connect(self._update_display)
        roi_groupbox.setLayout(roi_layout)
        roi_groupbox.setFixedHeight(200)
        roi_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        self._roi_groupbox = roi_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget(3, roi_groupbox)

    def get_subvolume_roi(self):
        if self._roi_groupbox.isChecked():
            return self._roi_widget.roi
        return None

    def _update_display(self):
        super(DvidDataSelectionBrowser, self)._update_display()
        hostname, dset_uuid, dataname, node_uuid = self.get_selection()

        enable_contents = self._repos_info is not None and dataname != "" and node_uuid != ""
        self._roi_groupbox.setEnabled(enable_contents)

        if not dataname or not node_uuid:
            self._roi_widget.initWithExtents("", (), (), ())
            return

        error_msg = None
        try:
            # Query the server
            raw_metadata = VoxelsAccessor.get_metadata(hostname, node_uuid,
                                                       dataname)
            voxels_metadata = VoxelsMetadata(raw_metadata)
        except DVIDException as ex:
            error_msg = ex.message
        except ErrMsg as ex:
            error_msg = str(ErrMsg)
        except VoxelsAccessor.BadRequestError as ex:
            # DVID will return an error if the selected dataset
            #  isn't a 'voxels' dataset and thus has no voxels metadata
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)
            return
        else:
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(True)

        if error_msg:
            QMessageBox.critical(self, "DVID Error", error_msg)
            self._roi_widget.initWithExtents("", (), (), ())
            return

        self._roi_widget.initWithExtents(voxels_metadata.axiskeys,
                                         voxels_metadata.shape,
                                         voxels_metadata.minindex,
                                         voxels_metadata.shape)
Ejemplo n.º 8
0
class DvidDataSelectionBrowser(ContentsBrowser):
    """
    A subclass of the libdvid ContentsBrowser that includes a widget for optional subvolume selection.
    """

    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super(DvidDataSelectionBrowser, self).__init__(*args, **kwargs)

        self._subvol_widget = SubregionRoiWidget(parent=self)

        subvol_layout = QVBoxLayout()
        subvol_layout.addWidget(self._subvol_widget)
        group_title = (
            "Restrict to subvolume (Right-click a volume name above to auto-initialize these subvolume parameters.)"
        )
        subvol_groupbox = QGroupBox(group_title, parent=self)
        subvol_groupbox.setCheckable(True)
        subvol_groupbox.setChecked(False)
        subvol_groupbox.setEnabled(False)
        subvol_groupbox.toggled.connect(self._update_status)
        subvol_groupbox.setLayout(subvol_layout)
        subvol_groupbox.setFixedHeight(200)
        subvol_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        self._subvol_groupbox = subvol_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget(3, subvol_groupbox)

        # Special right-click behavior.
        self._repo_treewidget.viewport().installEventFilter(self)

    def get_subvolume_roi(self):
        if self._subvol_groupbox.isChecked():
            return self._subvol_widget.roi
        return None

    def eventFilter(self, widget, event):
        """
        If the user right-clicks on a volume/roi name, it triggers special behavior:
        The subvolume widget is automatically initialized with extents matching the
        right-clicked volume, regardless of the currently selected volume.
        """
        if (
            widget is self._repo_treewidget.viewport()
            and event.type() == QEvent.MouseButtonPress
            and event.button() == Qt.RightButton
        ):
            item = self._repo_treewidget.itemAt(event.pos())
            repo_uuid, dataname, typename = item.data(0, Qt.UserRole).toPyObject()
            is_roi = typename == "roi"
            is_voxels = typename in ["labelblk", "uint8blk"]
            if (is_voxels or is_roi) and self._buttonbox.button(QDialogButtonBox.Ok).isEnabled():
                self._update_subvol_widget(
                    repo_uuid, dataname, typename
                )  # FIXME: we're passing the repo id instead of the node id. is that okay?
                self._subvol_groupbox.setChecked(True)
                return True
        return super(DvidDataSelectionBrowser, self).eventFilter(widget, event)

    def _update_status(self):
        super(DvidDataSelectionBrowser, self)._update_status()
        hostname, dset_uuid, dataname, node_uuid, typename = self.get_selection()

        enable_contents = self._repos_info is not None and dataname != "" and node_uuid != ""
        self._subvol_groupbox.setEnabled(enable_contents)

        if not dataname or not node_uuid:
            self._subvol_widget.initWithExtents("", (), (), ())
            return

        self._update_subvol_widget(node_uuid, dataname, typename)

    def _update_subvol_widget(self, node_uuid, dataname, typename):
        """
        Update the subvolume widget with the min/max extents of the given node and dataname.
        Note: The node and dataname do not necessarily have to match the currently 
              selected node and dataname.
              This enables the right-click behavior, which can be used to  
              limit your data volume to the size of a different data volume.
        """
        error_msg = None
        try:
            if typename == "roi":
                node_service = DVIDNodeService(self._hostname, str(node_uuid))
                roi_blocks_xyz = numpy.array(node_service.get_roi(str(dataname)))
                maxindex = tuple(DVID_BLOCK_WIDTH * (1 + numpy.max(roi_blocks_xyz, axis=0)))
                minindex = (0, 0, 0)  # Rois are always 3D
                axiskeys = "xyz"
                # If the current selection is a dataset, then include a channel dimension
                if self.get_selection().typename != "roi":
                    axiskeys = "cxyz"
                    minindex = (0,) + minindex
                    maxindex = (1,) + maxindex  # FIXME: This assumes that the selected data has only 1 channel...
            else:
                # Query the server
                raw_metadata = VoxelsAccessor.get_metadata(self._hostname, node_uuid, dataname)
                voxels_metadata = VoxelsMetadata(raw_metadata)
                maxindex = voxels_metadata.shape
                minindex = voxels_metadata.minindex
                axiskeys = voxels_metadata.axiskeys
                # If the current selection is a roi, then remove the channel dimension
                if self.get_selection().typename == "roi":
                    axiskeys = "xyz"
                    minindex = minindex[1:]
                    maxindex = maxindex[1:]
        except (DVIDException, ErrMsg) as ex:
            error_msg = str(ex)
            log_exception(logger)
        else:
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(True)

        if error_msg:
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)
            QMessageBox.critical(self, "DVID Error", error_msg)
            self._subvol_widget.initWithExtents("", (), (), ())
            return

        self._subvol_widget.initWithExtents(axiskeys, maxindex, minindex, maxindex)
Ejemplo n.º 9
0
class DvidDataSelectionBrowser(ContentsBrowser):
    """
    A subclass of the libdvid ContentsBrowser that includes a widget for optional subvolume selection.
    """
    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super( DvidDataSelectionBrowser, self ).__init__(*args, **kwargs)

        self._subvol_widget = SubregionRoiWidget( parent=self )

        subvol_layout = QVBoxLayout()
        subvol_layout.addWidget( self._subvol_widget )
        group_title = "Restrict to subvolume (Right-click a volume name above to auto-initialize these subvolume parameters.)"
        subvol_groupbox = QGroupBox(group_title, parent=self)
        subvol_groupbox.setCheckable(True)
        subvol_groupbox.setChecked(False)
        subvol_groupbox.setEnabled(False)
        subvol_groupbox.toggled.connect( self._update_status )
        subvol_groupbox.setLayout( subvol_layout )
        subvol_groupbox.setFixedHeight( 200 )
        subvol_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Minimum )
        self._subvol_groupbox = subvol_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget( 3, subvol_groupbox )

        # Special right-click behavior.
        self._repo_treewidget.viewport().installEventFilter(self)

    def get_subvolume_roi(self):
        if self._subvol_groupbox.isChecked():
            return self._subvol_widget.roi
        return None

    def eventFilter(self, widget, event):
        """
        If the user right-clicks on a volume/roi name, it triggers special behavior:
        The subvolume widget is automatically initialized with extents matching the
        right-clicked volume, regardless of the currently selected volume.
        """
        if widget is self._repo_treewidget.viewport() \
        and event.type() == QEvent.MouseButtonPress \
        and event.button() == Qt.RightButton:
            item = self._repo_treewidget.itemAt(event.pos())
            repo_uuid, dataname, typename = item.data(0, Qt.UserRole)
            is_roi = (typename == 'roi')
            is_voxels = (typename in ['labelblk', 'uint8blk'])
            if (is_voxels or is_roi) \
            and self._buttonbox.button(QDialogButtonBox.Ok).isEnabled():
                self._update_subvol_widget(repo_uuid, dataname, typename) # FIXME: we're passing the repo id instead of the node id. is that okay?
                self._subvol_groupbox.setChecked(True)
                return True
        return super(DvidDataSelectionBrowser, self).eventFilter(widget, event)

    def _update_status(self):
        super( DvidDataSelectionBrowser, self )._update_status()
        hostname, dset_uuid, dataname, node_uuid, typename = self.get_selection()

        enable_contents = self._repos_info is not None and dataname != "" and node_uuid != ""
        self._subvol_groupbox.setEnabled(enable_contents)

        if not dataname or not node_uuid:
            self._subvol_widget.initWithExtents( "", (), (), () )
            return
        
        self._update_subvol_widget(node_uuid, dataname, typename)
    
    def _update_subvol_widget(self, node_uuid, dataname, typename):
        """
        Update the subvolume widget with the min/max extents of the given node and dataname.
        Note: The node and dataname do not necessarily have to match the currently 
              selected node and dataname.
              This enables the right-click behavior, which can be used to  
              limit your data volume to the size of a different data volume.
        """
        error_msg = None
        try:
            if typename == "roi":
                node_service = DVIDNodeService(self._hostname, str(node_uuid))
                roi_blocks_zyx = numpy.array( node_service.get_roi(str(dataname)) )
                maxindex = tuple( DVID_BLOCK_WIDTH*(1 + numpy.max( roi_blocks_zyx, axis=0 )) )
                minindex = (0,0,0) # Rois are always 3D
                axiskeys = "zyx"
                # If the current selection is a dataset, then include a channel dimension
                if self.get_selection().typename != "roi":
                    axiskeys = "zyxc"
                    minindex = minindex + (0,)
                    maxindex = maxindex + (1,) # FIXME: This assumes that the selected data has only 1 channel...
            else:
                # Query the server
                raw_metadata = VoxelsAccessor.get_metadata( self._hostname, node_uuid, dataname )
                voxels_metadata = VoxelsMetadata( raw_metadata )
                maxindex = voxels_metadata.shape
                minindex = voxels_metadata.minindex
                axiskeys = voxels_metadata.axiskeys
                # If the current selection is a roi, then remove the channel dimension
                if self.get_selection().typename == "roi":
                    axiskeys = "zyx"
                    minindex = minindex[:-1]
                    maxindex = maxindex[:-1]
        except (DVIDException, ErrMsg) as ex:
            error_msg = str(ex)
            log_exception(logger)
        else:
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(True)

        if error_msg:
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)
            QMessageBox.critical(self, "DVID Error", error_msg)
            self._subvol_widget.initWithExtents( "", (), (), () )
            return

        self._subvol_widget.initWithExtents( axiskeys, maxindex, minindex, maxindex )
class DvidDataSelectionBrowser(ContentsBrowser):
    """
    A subclass of the libdvid ContentsBrowser that includes a widget for optional subvolume selection.
    """

    def __init__(self, *args, **kwargs):
        # Initialize the base class...
        super(DvidDataSelectionBrowser, self).__init__(*args, **kwargs)

        self._roi_widget = SubregionRoiWidget(parent=self)

        roi_layout = QVBoxLayout()
        roi_layout.addWidget(self._roi_widget)
        roi_groupbox = QGroupBox("Specify Region of Interest", parent=self)
        roi_groupbox.setCheckable(True)
        roi_groupbox.setChecked(False)
        roi_groupbox.setEnabled(False)
        roi_groupbox.toggled.connect(self._update_display)
        roi_groupbox.setLayout(roi_layout)
        roi_groupbox.setFixedHeight(200)
        roi_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        self._roi_groupbox = roi_groupbox

        # Add to the layout
        layout = self.layout()
        layout.insertWidget(3, roi_groupbox)

    def get_subvolume_roi(self):
        if self._roi_groupbox.isChecked():
            return self._roi_widget.roi
        return None

    def _update_display(self):
        super(DvidDataSelectionBrowser, self)._update_display()
        hostname, dset_uuid, dataname, node_uuid = self.get_selection()

        enable_contents = self._repos_info is not None and dataname != "" and node_uuid != ""
        self._roi_groupbox.setEnabled(enable_contents)

        if not dataname or not node_uuid:
            self._roi_widget.initWithExtents("", (), (), ())
            return

        error_msg = None
        try:
            # Query the server
            raw_metadata = VoxelsAccessor.get_metadata(hostname, node_uuid, dataname)
            voxels_metadata = VoxelsMetadata(raw_metadata)
        except DVIDException as ex:
            error_msg = ex.message
        except ErrMsg as ex:
            error_msg = str(ErrMsg)
        except VoxelsAccessor.BadRequestError as ex:
            # DVID will return an error if the selected dataset
            #  isn't a 'voxels' dataset and thus has no voxels metadata
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)
            return
        else:
            self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(True)

        if error_msg:
            QMessageBox.critical(self, "DVID Error", error_msg)
            self._roi_widget.initWithExtents("", (), (), ())
            return

        self._roi_widget.initWithExtents(
            voxels_metadata.axiskeys, voxels_metadata.shape, voxels_metadata.minindex, voxels_metadata.shape
        )