Skip to content

Instantly share code, notes, and snippets.

@sofroniewn
Created October 24, 2020 01:53
Show Gist options
  • Save sofroniewn/c825924fd6a3feef8fbdbb1ff05d0979 to your computer and use it in GitHub Desktop.
Save sofroniewn/c825924fd6a3feef8fbdbb1ff05d0979 to your computer and use it in GitHub Desktop.
extent object for napari
import numpy as np
from ..utils.events import EmitterGroup
class Extent:
"""Extent object holding minimum and maximum values of data.
Parameters
----------
transform : napari.utils.transforms.Transform, optional
Transform from data to world coordinates.
Attributes
----------
events : EmitterGroup
Event emitter group
data : (2, D) np.ndarray
Minimum and maximum values of the data in D dimensions
in the original data coordinates.
step : (D,) np.ndarray
Step values for appropriately sampling data in world
coordinates.
world : (2, D) np.ndarray
Minimum and maximum values of the data in D dimensions
mapped into world coordinates.
"""
def __init__(self, ndim, transform=None):
# Events:
self.events = EmitterGroup(
source=self,
auto_connect=True,
data=None,
step=None,
world=None,
)
self._data = np.array([0, 0, 0])
self._step = np.array([1, 1, 1])
self._world = np.array([1, 1, 1])
self._transform = transform
@property
def data(self):
"""np.ndarray: Minimum and maximum values in data coordinates."""
return self._data
@data.setter
def data(self, data):
self._data = data
self._world = transform_extent(self._data, self._transform)
self.events.world()
@property
def world(self):
"""np.ndarray: Minimum and maximum values in data coordinates."""
return self._world
@world.setter
def world(self, world):
self._world = world
self._data = transform_extent(self._world, self._transform.inverse)
self.events.world()
@property
def step(self):
"""np.ndarray: Values for sampling data in world coordinates."""
return self._step
@step.setter
def step(self, step):
self._step = step
self.events.step()
def transform_extent(input_extent, transform):
"""Transform extent from one coordinate system to another.
Note that the full nD bounding box is consider during the
transformation of an extent from one coordinate system
to another.
Parameters
----------
input_extent : (2, D) np.ndarray
Minimum and maximum values of the data in D dimensions
in either data coordinates or world coordinates.
transform : napari.utils.transforms.Transform, optional
Transform from either data to world coordinates or
world to data coordinates.
Returns
----------
output_extent : (2, D) np.ndarray
Minimum and maximum values of the data in D dimensions
in either data coordinates or world coordinates after
being transformed by the transform.
"""
# Get full nD bounding box
D = input_extent.shape[1]
full_input_extent = np.array(np.meshgrid(*input_extent.T)).T.reshape(
-1, D
)
full_output_extent = self._transform(full_input_extent)
output_extent = np.array(
[
np.min(full_output_extent, axis=0),
np.max(full_output_extent, axis=0),
]
)
return output_extent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment