ndv.models #
Models for ndv.
Classes:
-
ArrayDisplayModel–Model of how to display an array.
-
ArrayViewerModel–Options and state for the
ArrayViewer. -
ChannelMode–Channel display mode.
-
ClimPolicy–ABC for contrast limit policies.
-
ClimsManual–Manually specified contrast limits.
-
ClimsMinMax–Autoscale contrast limits based on the minimum and maximum values in the data.
-
ClimsPercentile–Autoscale contrast limits based on percentiles of the data.
-
ClimsStdDev–Automatically set contrast limits based on standard deviations from the mean.
-
DataWrapper–Interface for wrapping different array-like data types.
-
LUTModel–Representation of how to display a channel of an array.
-
NDVModel–Base evented model for NDV models.
-
RectangularROIModel–Representation of an axis-aligned rectangular Region of Interest (ROI).
-
ResolvedDisplayState–Frozen snapshot of resolved display state (ArrayDisplayModel + DataWrapper).
-
RingBuffer–Ring buffer structure with a given capacity and element type.
-
RingBufferWrapper–Wrapper for ring buffer objects.
ArrayDisplayModel #
Bases: NDVModel
Model of how to display an array.
An ArrayDisplayModel is used to specify how to display a multi-dimensional array. It specifies which axes are visible, how to reduce along axes that are not visible, how to display channels, and how to apply lookup tables to channels. It is typically paired with a ndv.DataWrapper in order to resolve axis keys and slice data.
Info
In the following types, Hashable is used to refer to a type that will typically be either an integer index or a string label for an axis.
Attributes:
-
visible_axes(tuple[Hashable, ...]) –Ordered list of axes to visualize, from slowest to fastest. e.g.
('Z', -2, -1) -
current_index(Mapping[Hashable, int | slice]) –The currently displayed position/slice along each dimension. e.g. {0: 0, 'time': slice(10, 20)} Not all axes need be present, and axes not present are assumed to be slice(None), meaning it is up to the controller of this model to restrict indices to an efficient range for retrieval. If the number of non-singleton axes is greater than
n_visible_axes, thenreducersare used to reduce the data along the remaining axes. -
reducers(Mapping[Hashable | None, ufunc]) –Function used to reduce data along axes remaining after slicing. Ideally, the ufunc should accept an
axisargument. (TODO: what happens if not?) -
default_reducer(ufunc) –Default reducer to use when no reducer is specified for an axis. By default, this is
numpy.max. -
channel_mode(ChannelMode) –How to display channel information:
GRAYSCALE: ignore channel axis, usedefault_lutCOMPOSITE: display all channels as a composite image, usinglutsCOLOR: display a single channel at a time, usinglutsRGBA: display as an RGB image, usingdefault_lut(except for cmap)
If
channel_modeis set to anything other thanGRAYSCALE, thenchannel_axismust be set to a valid axis; if nochannel_axisis set, at the time of display, theDataWrapperMAY guess thechannel_axis, and set it on the model. -
channel_axis(Hashable | None) –The dimension index or name of the channel dimension. The implication of setting channel_axis is that all elements along the channel dimension are shown, with different LUTs applied to each channel. If None, then a single lookup table is used for all channels (
luts[None]). NOTE: it is an error for channel_axis to be invisible_axes(or ignore it?) -
luts(Mapping[int | None, LUTModel]) –Instructions for how to display each channel of the array. Keys represent position along the dimension specified by
channel_axis. Values areLUTobjects that specify how to display the channel. The special keyNoneis used to represent a fallback LUT for all channels, and is used whenchannel_axisis None. It should always be present -
default_lut(LUTModel) –Default lookup table to use when no
LUTModelis specified for a channel inluts.
ArrayViewerModel #
Bases: NDVModel
Options and state for the ArrayViewer.
Attributes:
-
interaction_mode(InteractionMode) –Describes the current interaction mode of the Viewer.
-
show_controls((bool, optional)) –Control visibility of all controls at once. By default True.
-
show_3d_button((bool, optional)) –Whether to show the 3D button, by default True.
-
show_histogram_button((bool, optional)) –Whether to show the histogram button, by default True.
-
use_shared_histogram((bool, optional)) –Whether to use a shared histogram overlay for all channels, by default True. When True, per-channel histogram buttons are hidden.
-
show_reset_zoom_button((bool, optional)) –Whether to show the reset zoom button, by default True.
-
show_roi_button((bool, optional)) –Whether to show the ROI button, by default False.
-
show_channel_mode_selector((bool, optional)) –Whether to show the channel mode selector, by default True.
-
show_play_button((bool, optional)) –Whether to show the play button, by default True.
-
show_progress_spinner((bool, optional)) –Whether to show the progress spinner, by default False.
-
show_data_info((bool, optional)) –Whether to show shape, dtype, size, etc. about the array
-
default_luts((list[Colormap], optional)) –List of colormaps to use when populating the LUT dropdown menu in the viewer. Only editable upon initialization. Values may be any
cmapColormapLike object (most commonly, just a string name of the colormap, like "gray" or "viridis").
Classes:
-
ArrayViewerModelEvents–Signal group for ArrayViewerModel.
ArrayViewerModelEvents #
ChannelMode #
Channel display mode.
Attributes:
-
GRAYSCALE(str) –The array is displayed as a single channel, with a single lookup table applied. In this mode, there effective is no channel axis: all non-visible dimensions have sliders, and there is a single LUT control (the
default_lut). -
COMPOSITE(str) –Display all (or a subset of) channels as a composite image, with a different lookup table applied to each channel. In this mode, the slider for the channel axis is hidden by default, and LUT controls for each channel are shown.
-
COLOR(str) –Display a single channel at a time as a color image, with a channel-specific lookup table applied. In this mode, the slider for the channel axis is shown, and the user can select which channel to display. LUT controls are shown for all channels.
-
RGBA(str) –The array is displayed as an RGB image, with a single lookup table applied. In this mode, the slider for the channel axis is hidden, and a single LUT control is shown. Only valid when channel axis has length <= 4.
-
RGB(str) –Alias for RGBA.
Methods:
-
is_multichannel–Return whether this mode displays multiple channels.
is_multichannel #
is_multichannel() -> bool
Return whether this mode displays multiple channels.
If is_multichannel is True, then the channel_axis slider should be hidden.
Source code in src/ndv/models/_array_display_model.py
112 113 114 115 116 117 | |
ClimPolicy #
ABC for contrast limit policies.
Methods:
-
get_limits–Return the contrast limits for the given image.
get_limits abstractmethod #
Return the contrast limits for the given image.
Source code in src/ndv/models/_lut_model.py
29 30 31 | |
ClimsManual #
ClimsMinMax #
ClimsPercentile #
Bases: ClimPolicy
Autoscale contrast limits based on percentiles of the data.
Attributes:
-
min_percentile(float) –The lower percentile for the contrast limits.
-
max_percentile(float) –The upper percentile for the contrast limits.
ClimsStdDev #
Bases: ClimPolicy
Automatically set contrast limits based on standard deviations from the mean.
Attributes:
-
n_stdev(float) –Number of standard deviations to use.
-
center(Optional[float]) –Center value for the standard deviation calculation. If None, the mean is used.
DataWrapper #
DataWrapper(data: ArrayT)
Interface for wrapping different array-like data types.
DataWrapper.create() is a factory method that returns a DataWrapper instance for the given data type. If your datastore type is not supported, you may implement a new DataWrapper subclass to handle your data type. To do this, import and subclass DataWrapper, and (minimally) implement the supports and isel methods. Ensure that your class is imported before the DataWrapper.create method is called, and it will be automatically detected and used to wrap your data.
This base class provides basic support for numpy-like array types. If the data supports getitem and shape attributes, it will work. If the data does not support getitem, the subclass MUST implement the isel method. If the data does not have a shape attribute, the subclass MUST implement the dims and coords properties.
Methods:
-
axis_scales–Return per-axis scale factors from coordinate spacing.
-
channel_names–Return channel display names from data metadata.
-
clear_cache–Clear any cached properties.
-
create–Create a DataWrapper instance for the given data.
-
guess_channel_axis–Return the (best guess) axis name for the channel dimension.
-
guess_z_axis–Return the (best guess) axis name for the z (3rd spatial) dimension.
-
isel–Return a slice of the data as a numpy array.
-
normalize_axis_key–Return positive index for
axis(which can be +/- int or str label). -
sizes–Return the sizes of the dimensions.
-
summary_info–Return info label with information about the data.
-
supports–Return True if this wrapper can handle the given object.
Attributes:
-
axis_map(Mapping[Hashable, int]) –Mapping of ALL valid axis keys to normalized, positive integer keys.
-
coords(Mapping[Hashable, Sequence]) –Return the coordinates for the data.
-
data(ArrayT) –Return the data being wrapped.
-
data_changed–Signal emitted when the data changes.
-
dims(tuple[Hashable, ...]) –Return the dimension labels for the data.
-
dims_changed–Signal to emit when the dimensions of the data change.
-
dtype(dtype) –Return the dtype for the data.
-
significant_bits(int | None) –Number of significant bits per sample, if known from metadata.
Source code in src/ndv/models/_data_wrapper.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | |
axis_map cached property #
Mapping of ALL valid axis keys to normalized, positive integer keys.
data_changed class-attribute instance-attribute #
data_changed = Signal()
Signal emitted when the data changes.
NOTE: It is up to data wrappers, or even end-users to emit this signal when the data object changes. We do not currently use object proxies to spy on mutation of the underlying data.
dims_changed class-attribute instance-attribute #
dims_changed = Signal()
Signal to emit when the dimensions of the data change.
NOTE: It is up to data wrappers, or even end-users to emit this signal when the dimensions/shape of the wrapped _data object changes.
significant_bits property #
significant_bits: int | None
Number of significant bits per sample, if known from metadata.
axis_scales #
Return per-axis scale factors from coordinate spacing.
Source code in src/ndv/models/_data_wrapper.py
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | |
channel_names #
Return channel display names from data metadata.
Source code in src/ndv/models/_data_wrapper.py
320 321 322 323 324 325 326 327 328 329 330 331 332 | |
clear_cache #
clear_cache() -> None
Clear any cached properties.
Source code in src/ndv/models/_data_wrapper.py
352 353 354 355 | |
create classmethod #
create(data: ArrayT) -> DataWrapper[ArrayT]
Create a DataWrapper instance for the given data.
This method will detect all subclasses of DataWrapper and check them in order of their PRIORITY class variable. The first subclass that supports the given data will be used to wrap it.
Tip
This means that you can subclass DataWrapper to handle new data types. Just make sure that your subclass is imported before calling create.
If no subclasses support the data, a NotImplementedError is raised.
If an instance of DataWrapper is passed in, it will be returned as-is.
Source code in src/ndv/models/_data_wrapper.py
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | |
guess_channel_axis #
guess_channel_axis() -> Hashable | None
Return the (best guess) axis name for the channel dimension.
Source code in src/ndv/models/_data_wrapper.py
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | |
guess_z_axis #
guess_z_axis() -> Hashable | None
Return the (best guess) axis name for the z (3rd spatial) dimension.
Source code in src/ndv/models/_data_wrapper.py
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | |
isel #
Return a slice of the data as a numpy array.
index will look like (e.g.) {0: slice(0, 10), 1: 5}. The default implementation converts the index to a tuple of the same length as the self.dims, populating missing keys with slice(None), and then slices the data array using getitem.
Source code in src/ndv/models/_data_wrapper.py
147 148 149 150 151 152 153 154 155 156 157 158 159 | |
normalize_axis_key #
Return positive index for axis (which can be +/- int or str label).
Source code in src/ndv/models/_data_wrapper.py
308 309 310 311 312 313 314 315 316 317 318 | |
sizes #
Return the sizes of the dimensions.
Source code in src/ndv/models/_data_wrapper.py
238 239 240 | |
summary_info #
summary_info() -> str
Return info label with information about the data.
Source code in src/ndv/models/_data_wrapper.py
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | |
supports abstractmethod classmethod #
Return True if this wrapper can handle the given object.
Any exceptions raised by this method will be suppressed, so it is safe to directly import necessary dependencies without a try/except block.
Source code in src/ndv/models/_data_wrapper.py
120 121 122 123 124 125 126 127 | |
LUTModel #
Bases: NDVModel
Representation of how to display a channel of an array.
Attributes:
-
name(str) –Display name for this channel. Empty string means no explicit name.
-
visible(bool) –Whether to display this channel. NOTE: This has implications for data retrieval, as we may not want to request channels that are not visible. See
ArrayDisplayModel.current_index. -
cmap(Colormap) –cmap.Colormapto use for this channel. This can be expressed as any channel. This can be expressed as any "colormap like" object -
clims(Union[ClimsManual, ClimsPercentile, ClimsStdDev, ClimsMinMax]) –Method for determining the contrast limits for this channel. If a 2-element
tupleorlistis provided, it is interpreted as a manual contrast limit. -
bounds(tuple[float | None, float | None]) –Optional extrema for limiting the range of the contrast limits
-
gamma(float) –Gamma applied to the data before applying the colormap. By default,
1.0.
NDVModel #
Bases: BaseModel
Base evented model for NDV models.
Uses pydantic.BaseModel and psygnal.SignalGroupDescriptor.
RectangularROIModel #
Bases: NDVModel
Representation of an axis-aligned rectangular Region of Interest (ROI).
Attributes:
-
visible(bool) –Whether to display this roi.
-
bounding_box(tuple[tuple[float, float], tuple[float, float]]) –The minimum and maximum (x, y) points of the region in data space (i.e. array indices, not scaled world coordinates). These two points define an axis-aligned bounding box.
ResolvedDisplayState dataclass #
ResolvedDisplayState(
visible_axes: tuple[int, ...],
channel_axis: int | None,
channel_mode: ChannelMode,
current_index: dict[int, int | slice],
data_coords: dict[int, tuple],
hidden_sliders: frozenset[Hashable],
rgba_channel_count: int,
summary_info: str,
visible_scales: tuple[float, ...],
)
Frozen snapshot of resolved display state (ArrayDisplayModel + DataWrapper).
At any given time, the viewer's display state is influenced by both the current ArrayDisplayModel (e.g. which axes are visible, channel mode, current_index), which is mutable and can be updated by the user, and the DataWrapper, which has awareness of the underlying data (e.g. dimension names, coordinates, metadata).
The term "resolution" here refers to the process of taking the user's "intentions", as expressed in the ArrayDisplayModel, and resolving them against the reality of the data, as represented by the DataWrapper. This includes normalizing axis keys to positive integers, injecting values derived from the data (e.g. guessing a channel axis or inferring coordinates), and computing derived state.
The output of that resolution process is this ResolvedDisplayState, which is a deterministic, immutable, hashable snapshot of the display state that can be used for diffing and driving the actual data slicing and visualization logic.
Produced by resolve(). Used for diffing in ArrayViewer._apply_changes().
RingBuffer #
RingBuffer(
max_capacity: int,
dtype: DTypeLike = float,
*,
allow_overwrite: bool = True,
create_buffer: Callable[
[int, DTypeLike], NDArray
] = empty,
)
Bases: Sequence
Ring buffer structure with a given capacity and element type.
Parameters:
-
(max_capacity#int) –The maximum capacity of the ring buffer.
-
(dtype#DTypeLike, default:float) –Desired type (and shape) of individual buffer elements. This is passed to
np.empty, so it can be any dtype-like object. Common scenarios will be: - a fixed dtype (e.g.int,np.uint8,'u2',np.dtype('f4')) - a(fixed_dtype, shape)tuple (e.g.('uint16', (512, 512))) -
(allow_overwrite#bool, default:True) –If false, throw an IndexError when trying to append to an already full buffer.
-
(create_buffer#Callable[[int, DTypeLike], NDArray], default:empty) –A callable that creates the underlying array. May be used to customize the initialization of the array. Defaults to
np.empty.
Notes
Vendored from numpy-ringbuffer, by Eric Wieser (MIT License). And updated with typing and signals.
Methods:
-
append–Append a value to the right end of the buffer.
-
appendleft–Append a value to the left end of the buffer.
-
extend–Extend the buffer with the given values.
-
extendleft–Prepend the buffer with the given values.
-
pop–Pop a value from the right end of the buffer.
-
popleft–Pop a value from the left end of the buffer.
Attributes:
-
dtype(dtype) –Return the dtype of the buffer.
-
is_full(bool) –True if there is no more space in the buffer.
-
maxlen(int) –Return the maximum capacity of the buffer.
-
shape(tuple[int, ...]) –Return the shape of the valid buffer (excluding unused space).
Source code in src/ndv/models/_ring_buffer.py
76 77 78 79 80 81 82 83 84 85 86 87 88 | |
shape property #
Return the shape of the valid buffer (excluding unused space).
append #
append(value: ArrayLike) -> None
Append a value to the right end of the buffer.
Source code in src/ndv/models/_ring_buffer.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
appendleft #
appendleft(value: ArrayLike) -> None
Append a value to the left end of the buffer.
Source code in src/ndv/models/_ring_buffer.py
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | |
extend #
extend(values: ArrayLike) -> None
Extend the buffer with the given values.
Source code in src/ndv/models/_ring_buffer.py
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | |
extendleft #
extendleft(values: ArrayLike) -> None
Prepend the buffer with the given values.
Source code in src/ndv/models/_ring_buffer.py
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
pop #
pop() -> ndarray
Pop a value from the right end of the buffer.
Source code in src/ndv/models/_ring_buffer.py
147 148 149 150 151 152 153 154 155 | |
popleft #
popleft() -> ndarray
Pop a value from the left end of the buffer.
Source code in src/ndv/models/_ring_buffer.py
157 158 159 160 161 162 163 164 165 | |
RingBufferWrapper #
RingBufferWrapper(
max_capacity: int | RingBuffer,
dtype: DTypeLike | None = None,
*,
allow_overwrite: bool = True,
)
Bases: DataWrapper[RingBuffer]
Wrapper for ring buffer objects.
Methods:
-
append–Append a value to the right end of the buffer.
-
appendleft–Append a value to the left end of the buffer.
-
axis_scales–Return per-axis scale factors from coordinate spacing.
-
channel_names–Return channel display names from data metadata.
-
clear_cache–Clear any cached properties.
-
create–Create a DataWrapper instance for the given data.
-
guess_channel_axis–Return the (best guess) axis name for the channel dimension.
-
guess_z_axis–Return the (best guess) axis name for the z (3rd spatial) dimension.
-
isel–Return a slice of the data as a numpy array.
-
normalize_axis_key–Return positive index for
axis(which can be +/- int or str label). -
pop–Pop a value from the right end of the buffer.
-
popleft–Pop a value from the left end of the buffer.
-
sizes–Return the sizes of the dimensions.
-
summary_info–Return info label with information about the data.
Attributes:
-
axis_map(Mapping[Hashable, int]) –Mapping of ALL valid axis keys to normalized, positive integer keys.
-
coords(Mapping) –Return the coordinates for the data.
-
data(ArrayT) –Return the data being wrapped.
-
data_changed–Signal emitted when the data changes.
-
dims(tuple[int, ...]) –Return the dimensions of the data.
-
dims_changed–Signal to emit when the dimensions of the data change.
-
dtype(dtype) –Return the dtype for the data.
-
significant_bits(int | None) –Number of significant bits per sample, if known from metadata.
Source code in src/ndv/models/_data_wrapper.py
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | |
axis_map cached property #
Mapping of ALL valid axis keys to normalized, positive integer keys.
data_changed class-attribute instance-attribute #
data_changed = Signal()
Signal emitted when the data changes.
NOTE: It is up to data wrappers, or even end-users to emit this signal when the data object changes. We do not currently use object proxies to spy on mutation of the underlying data.
dims_changed class-attribute instance-attribute #
dims_changed = Signal()
Signal to emit when the dimensions of the data change.
NOTE: It is up to data wrappers, or even end-users to emit this signal when the dimensions/shape of the wrapped _data object changes.
significant_bits property #
significant_bits: int | None
Number of significant bits per sample, if known from metadata.
append #
append(value: ArrayLike) -> None
Append a value to the right end of the buffer.
Source code in src/ndv/models/_data_wrapper.py
585 586 587 | |
appendleft #
appendleft(value: ArrayLike) -> None
Append a value to the left end of the buffer.
Source code in src/ndv/models/_data_wrapper.py
589 590 591 | |
axis_scales #
Return per-axis scale factors from coordinate spacing.
Source code in src/ndv/models/_data_wrapper.py
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | |
channel_names #
Return channel display names from data metadata.
Source code in src/ndv/models/_data_wrapper.py
320 321 322 323 324 325 326 327 328 329 330 331 332 | |
clear_cache #
clear_cache() -> None
Clear any cached properties.
Source code in src/ndv/models/_data_wrapper.py
352 353 354 355 | |
create classmethod #
create(data: ArrayT) -> DataWrapper[ArrayT]
Create a DataWrapper instance for the given data.
This method will detect all subclasses of DataWrapper and check them in order of their PRIORITY class variable. The first subclass that supports the given data will be used to wrap it.
Tip
This means that you can subclass DataWrapper to handle new data types. Just make sure that your subclass is imported before calling create.
If no subclasses support the data, a NotImplementedError is raised.
If an instance of DataWrapper is passed in, it will be returned as-is.
Source code in src/ndv/models/_data_wrapper.py
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | |
guess_channel_axis #
guess_channel_axis() -> Hashable | None
Return the (best guess) axis name for the channel dimension.
Source code in src/ndv/models/_data_wrapper.py
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | |
guess_z_axis #
guess_z_axis() -> Hashable | None
Return the (best guess) axis name for the z (3rd spatial) dimension.
Source code in src/ndv/models/_data_wrapper.py
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | |
isel #
Return a slice of the data as a numpy array.
index will look like (e.g.) {0: slice(0, 10), 1: 5}. The default implementation converts the index to a tuple of the same length as the self.dims, populating missing keys with slice(None), and then slices the data array using getitem.
Source code in src/ndv/models/_data_wrapper.py
147 148 149 150 151 152 153 154 155 156 157 158 159 | |
normalize_axis_key #
Return positive index for axis (which can be +/- int or str label).
Source code in src/ndv/models/_data_wrapper.py
308 309 310 311 312 313 314 315 316 317 318 | |
pop #
pop() -> ndarray
Pop a value from the right end of the buffer.
Source code in src/ndv/models/_data_wrapper.py
593 594 595 | |
popleft #
popleft() -> ndarray
Pop a value from the left end of the buffer.
Source code in src/ndv/models/_data_wrapper.py
597 598 599 | |
sizes #
Return the sizes of the dimensions.
Source code in src/ndv/models/_data_wrapper.py
238 239 240 | |
summary_info #
summary_info() -> str
Return info label with information about the data.
Source code in src/ndv/models/_data_wrapper.py
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | |