You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thank you for your interest in contributing to ndevio! This document provides guidelines for development and contributions.
4
+
5
+
## Development Setup
6
+
7
+
### Using pip
8
+
9
+
For development, clone the repository and install with the dev dependency group:
10
+
11
+
```bash
12
+
git clone https://github.com/ndev-kit/ndevio.git
13
+
cd ndevio
14
+
pip install -e . --group dev
15
+
```
16
+
17
+
This includes pytest, pytest-cov, pytest-qt, tox-uv, napari, and pyqt6.
18
+
19
+
Run tests with:
20
+
21
+
```bash
22
+
pytest -v --cov=ndevio --cov-report=html
23
+
```
24
+
25
+
### Using Pixi
26
+
27
+
You can use [Pixi](https://pixi.sh) for reproducible development environments:
28
+
29
+
```bash
30
+
git clone https://github.com/ndev-kit/ndevio.git
31
+
cd ndevio
32
+
pixi install -e dev
33
+
pixi run -e dev test
34
+
```
35
+
36
+
Or activate the environment and run commands directly:
37
+
38
+
```bash
39
+
pixi shell -e dev
40
+
pytest -v
41
+
```
42
+
43
+
## Code Architecture
44
+
45
+
### Mature Patterns
46
+
47
+
The following components represent stable, mature patterns that reflect the goals of the ndevio API:
48
+
49
+
#### `nImage` Class
50
+
51
+
The `nImage` class ([nimage.py](src/ndevio/nimage.py)) extends bioio's `BioImage` with napari-specific functionality. This is the **core programmatic API** for ndevio and follows these principles:
-**Lazy loading support**: Automatically determines whether to load data in-memory or use dask based on file size and available RAM
55
+
-**Layer data tuples**: Provides `get_layer_data_tuples()` method that returns napari-ready `LayerDataTuple` objects
56
+
-**Channel splitting**: Handles multi-channel images by creating separate layer data tuples per channel
57
+
-**Separation of concerns**: No Qt or napari widget dependencies in core functionality
58
+
59
+
#### `_napari_reader` Module
60
+
61
+
The napari reader plugin ([_napari_reader.py](src/ndevio/_napari_reader.py)) implements the npe2 reader specification:
62
+
63
+
-**Plugin discovery**: Registers file extensions and provides reader selection
64
+
-**Scene handling**: Integrates with the Scene Widget for multi-scene files
65
+
-**Settings integration**: Respects user preferences from ndev-settings
66
+
-**Error handling**: Provides helpful suggestions for missing bioio plugins
67
+
68
+
This module is the **bridge between napari and nImage**, translating drag-and-drop file operations into proper layer creation.
69
+
70
+
### Key Design Principles
71
+
72
+
1.**Core logic separate from UI**: Business logic in `nimage.py`, `_layer_utils.py`, etc. should have **no Qt or napari imports** (except type hints)
73
+
2.**Lazy imports**: Expensive imports (Qt, napari widgets) should be lazy-loaded to keep startup fast
74
+
3.**Settings-driven behavior**: Use [ndev-settings] for user-configurable behavior rather than hardcoding choices
75
+
4.**bioio compatibility**: Stay aligned with bioio's data model and avoid reinventing functionality
76
+
77
+
## Testing
78
+
79
+
⚠️ **Tests are in poor shape**. Some tests were generated by an LLM without thorough verification and may not reflect actual functionality or edge cases. Sorry!
**A generalized image format reader for napari built on top of [bioio]**
13
+
14
+
`ndevio` provides flexible, metadata-aware image I/O for images in napari.
15
+
Originally developed as part of napari-ndev, `ndevio` has since been separated into its own plugin as part of the [ndev-kit] and is intended to be a feature-rich and easier to maintain spiritual successor to [napari-aicsimageio].
13
16
14
17
----------------------------------
15
18
16
-
This [napari] plugin was generated with [copier] using the [napari-plugin-template].
19
+
## Features
17
20
18
-
<!--
19
-
Don't miss the full getting started guide to set up your new package:
-**Extensive format support** via [bioio] and its plugin system — read OME-TIFF, OME-Zarr, common image and movie formats, proprietary formats (CZI, LIF, ND2), and many more (with bioformats)!
22
+
-**Multi-scene handling** — interactive widget for selecting between scenes/positions in multi-scene files
23
+
-**Configurable behavior** via [ndev-settings] — customize reader priority, multi-scene handling, and more
-**Programmatic API** — `nImage` class for napari-ready metadata extraction
26
+
-**Batch utilities** — legacy widget for batch concatenation (with [nbatch]) and metadata management, with features being superseded by [napari-metadata]
27
+
-**Sample data** — demonstrates ndevio metadata handling and capabilities
21
28
22
-
and review the napari docs for plugin developers:
23
-
https://napari.org/stable/plugins/index.html
24
-
-->
29
+

25
30
26
31
## Installation
27
32
28
-
You can install `ndevio`via [pip]:
33
+
You can install `ndevio`from [PyPI] or via the napari plugin manager:
29
34
30
35
```bash
31
36
pip install ndevio
32
37
```
33
38
34
-
If napari is not already installed, you can install `ndevio` with napari and Qt via:
39
+
If you would like to try out ndevio, you can run napari in a temporary environment with [uv]:
To contibute to ndevio or experiment with the latest features, see [Contributing.md](CONTRIBUTING.md) for development setup instructions. Conda-forge availability is coming soon!
If your image format is not supported by the default readers, then you will get a warning and (by default in napari) a widget to install the suggested reader.
56
57
If you know of your additional proprietary formats, install the appropriate bioio reader.
58
+
See the [bioio documentation](https://bioio-devs.github.io/bioio/) for the full list of available readers.
59
+
**Note**: The use of `bioio-bioformats` has not been fully tested and may have issues. Please [file an issue] if you encounter problems.
57
60
58
-
```bash
59
-
# CZI files (GPL-3 licensed)
60
-
pip install bioio-czi
61
+
## Usage
61
62
62
-
# LIF files (GPL-3 licensed)
63
-
pip install bioio-lif
63
+
### In napari
64
64
65
-
# Bio-Formats for many formats (behavior not guaranteed)
66
-
pip install bioio-bioformats
67
-
```
65
+
Simply drag and drop image files into napari. `ndevio` handles the rest! To learn more about the decisions that ndevio (and its settings) makes when loading images, see [How ndevio Handles Images](#how-ndevio-handles-images) below.
68
66
69
-
See the [bioio documentation](https://bioio-devs.github.io/bioio/) for the full list of available readers.
67
+
#### Multi-scene Images
70
68
71
-
### Pixi Usage
69
+
When opening multi-scene files (e.g., multi-position acquisitions, mosaics), a **Scene Widget** appears in the viewer, allowing you to select which scene to display. Configure default behavior via the Settings widget.
72
70
73
-
You can use [Pixi](https://pixi.sh) for reproducible development environments:
71
+
#### Bioio Reader Plugin Installation Widget
74
72
75
-
```bash
76
-
git clone https://github.com/ndev-kit/ndevio.git
77
-
cd ndevio
78
-
pixi install -e dev
79
-
pixi run -e dev test
80
-
```
73
+
If you open a file that requires a bioio reader not currently installed, ndevio will display a **BioIO Plugin Installation widget** in napari suggesting the appropriate plugin to install.
81
74
82
-
Or activate the environment and run commands directly:
This widget taps into the `napari-plugin-manager` to install the bioio reader plugin from PyPI via a GUI. You may invoke this widget manually at any time via `Plugins > ndevio > Install BioIO Reader Plugins` to install any additional bioio reader plugin *and* update any currently installed plugins.
88
78
89
-
###Development
79
+
#### Settings Widget
90
80
91
-
For development, clone the repository and install with the dev dependency group:
81
+
Access **ndevio settings** via `Plugins > ndev-settings > Settings` to customize:
92
82
93
-
```bash
94
-
git clone https://github.com/ndev-kit/ndevio.git
95
-
cd ndevio
96
-
pip install -e . --group dev
97
-
```
83
+
-**Preferred reader**: Override bioio's default plugin selection priority (useful for formats with multiple compatible readers)
84
+
-**Multi-scene handling**: Choose whether to show the scene widget, view all scenes as a stack, or view only the first scene
85
+
-**Plugin suggestions**: Enable/disable automatic plugin installation prompts for unsupported formats
98
86
99
-
This includes pytest, pytest-cov, pytest-qt, tox-uv, napari, and pyqt6.
87
+

100
88
101
-
Run tests with:
89
+
These settings are managed by [ndev-settings] and persist across napari sessions.
102
90
103
-
```bash
104
-
pytest -v --cov=ndevio --cov-report=html
91
+
#### Utilities Widget
92
+
93
+
Access via `Plugins > ndevio > Utilities` for:
94
+
95
+
-**Batch concatenation** of images
96
+
-**Metadata management**
97
+
-**Export** as OME-TIFF or figure (PNG)
98
+
99
+
**Note**: Elements of this widget are being superseded by [napari-metadata] for more comprehensive metadata handling.
100
+
**Note 2:** This widget was built during napari-ndev mono-repo development and does not fully reflect the design goals of ndevio. It will remain functional, but expect future versions to look different.
101
+
102
+
### Programmatic Usage with `nImage`
103
+
104
+
The `nImage` class extends [bioio]'s `BioImage` with napari-specific functionality:
105
+
106
+
```python
107
+
from ndevio import nImage
108
+
from napari import Viewer
109
+
110
+
# Load image with automatic metadata extraction
111
+
img = nImage("path/to/image.czi")
112
+
113
+
# Because nImage subclasses BioImage, all BioImage methods are available
# Access napari-ready properties, note that channel and singleton dimensions are dropped
117
+
img.layer_data.shape) # e.g. (15, 4, 256, 256) - still includes channel dimbecause it has not yet been converted to a list of LayerDataTuples
118
+
img.layer_scale) # e.g., (1.0, 0.2, 0.2) - time interval + physical scale per dimension, napari ready
119
+
img.layer_axis_labels) # e.g., ('T', 'Y', 'X')
120
+
img.layer_units) # e.g., ('s', 'µm', 'µm')
121
+
img.layer_metadata) # e.g., a dictionary containing the 1) full BioImage object, 2) raw_image metadata and 3) OME metadata (if parsed) - accessible via `viewer.layers[n].metadata`
122
+
123
+
# A convenience method to get napari LayerDataTuples with nImage metadata for napari
124
+
viewer = Viewer()
125
+
for ldt in img.get_layer_data_tuples():
126
+
viewer.add_layer(ldt)
105
127
```
106
128
129
+
### Sample Data
130
+
131
+
ndevio includes sample datasets accessible via `File > Open Sample > ndevio`.
132
+
These samples use the `nImage` API to demonstrate the metadata handling.
133
+
134
+

135
+
136
+
- 2D neural cells in a dish imaged with 4 channels, with corresponding segmentation labels
137
+
- 2D brain slice with 3 different transcription factor antibody stains
138
+
- A single 2D+Time sample from a scratched retinal epithelial cell culture, including auto-detected labels in the same file.
139
+
- the napari-ndev logo as a .png
140
+
141
+
## How ndevio Handles Images
142
+
143
+
### Metadata
144
+
145
+
Image metadata is extracted from bioio and converted to napari layer metadata based on the current napari convention to squeeze out singleton dimensions (i.e. drop dimensions of size 1):
146
+
147
+
-**Full metadata** available at `viewer.layers[n].metadata`
148
+
-**Time and physical scale** automatically applied to layers from OME metadata or file headers
149
+
-**Dimension labels** (T, C, Z, Y, X) preserved in `axis_labels`
150
+
-**Physical units** (µm, nm, etc.) stored in layer metadata
151
+
152
+
### Memory Management
153
+
154
+
Images are loaded **in-memory** or **lazily** (via dask) automatically based on:
155
+
156
+
- File size < 4 GB **AND**
157
+
- File size < 30% of available RAM
158
+
159
+
### Multi-channel Images
160
+
161
+
Multi-channel images are **always split** into individual layers (one per channel), using channel names from metadata when available. Images are added with colorblind-friendly colormaps.
162
+
163
+
### Mosaic/Tiled Images
164
+
165
+
Images with tiles (e.g., stitched acquisitions) are **automatically stitched together** if the reader supports this behavior.
166
+
167
+
### RGB Images
168
+
169
+
RGB(A) images are currently added to the viewer as a single RGB(A) layer, according to napari conventions.
170
+
RGB(A) images are identified by containing the Samples ('S') dimension by bioio, which nominally exists for images with the last (`-1`) dimension being of size 3 or 4.
171
+
172
+
### Detection of Labels/Segmentation Layers
173
+
174
+
If an image contains a channel name or file name suggestive of a labels layer, ndevio will add that channel as a labels layer in napari. Mixed image and label files are possible by having information in the channel names (e.g., `["DAPI", "DAPI-labels"]`).
175
+
176
+
### Customization
177
+
178
+
If you need different behavior for any of these automated handling rules, please [file an issue] — we may be able to add settings to configure them!
179
+
180
+
## Coming Soon
181
+
182
+
**Writers for OME-TIFF and OME-Zarr** with round-trip napari metadata support!
183
+
107
184
## Contributing
108
185
109
-
Contributions are very welcome. Tests can be run with [tox], please ensure
110
-
the coverage at least stays the same before you submit a pull request.
186
+
Contributions are very welcome! Please see [Contributing.md](CONTRIBUTING.md) for development setup and guidelines.
111
187
112
188
## License
113
189
@@ -119,10 +195,16 @@ Distributed under the terms of the [BSD-3] license,
119
195
If you encounter any problems, please [file an issue] along with a detailed description.
120
196
121
197
[file an issue]: https://github.com/ndev-kit/ndevio/issues
0 commit comments