Contributing¶
Thank you for your interest in contributing to SenoQuant. This guide helps you set up a development environment and follow the project workflow.
Development setup¶
Environment creation¶
conda create -n senoquant-dev python=3.11
conda activate senoquant-dev
pip install uv
uv pip install "napari[all]"
uv pip install -e .
Verify installation¶
Launch napari and open the plugin from the Plugins menu.
napari
Select Plugins -> SenoQuant to verify the plugin loads correctly.
Testing¶
Running tests¶
The project uses pytest with an 80% coverage requirement.
conda activate senoquant-dev
pytest
Test configuration¶
- Config file:
pytest.inispecifies coverage thresholds and test discovery. - Fixtures:
tests/conftest.pyprovides stubs for headless GUI dependencies (DummySignal and mock napari layers). - Coverage: Tests require >=80% line coverage to pass.
Writing tests¶
When adding new functionality:
- Create test modules in the corresponding
tests/subdirectory. - Use fixtures from
conftest.pyfor napari layer mocks. - Leverage
tmp_pathfor isolated file operations. - Mock external dependencies (BioIO and Qt signals) where appropriate.
Example test structure:
def test_new_feature(tmp_path):
# Arrange.
test_file = tmp_path / "test.tif"
test_file.write_bytes(b"fake data")
# Act.
result = my_function(test_file)
# Assert.
assert result is not None
Headless testing¶
Tests run without a display server.
- Qt dependencies are stubbed in
conftest.py. - Avoid importing GUI modules at top level in test files.
- Use
pytest-qtfor Qt-specific testing when needed.
Documentation¶
Building documentation locally¶
Install documentation dependencies.
pip install mkdocs mkdocs-material mkdocstrings[python]
Serve documentation locally for live preview.
mkdocs serve
Visit http://127.0.0.1:8000 to view the docs.
Build the static site.
mkdocs build
Documentation structure¶
- User guide (
docs/user/): End-user documentation for each plugin tab. - Developer guide (
docs/developer/): Architecture, models, features, and contribution details. - API reference (
docs/api/): Auto-generated via mkdocstrings (do not edit manually).
Writing documentation¶
- Use Markdown with Material for MkDocs extensions.
- Include code examples with proper syntax highlighting.
- Add screenshots to
docs/assets/for UI documentation. - Reference specific line numbers when linking to code, for example:
[file.py](file.py#L10).
Code conventions¶
Style guidelines¶
- Type hints: Use modern Python 3.11+ type annotations.
- Docstrings: Use NumPy style for public APIs.
- Imports: Use absolute imports from
senoquant. - File paths: Use
pathlib.Pathinstead of string paths.
Architecture patterns¶
- Frontend/backend split: Each tab has
frontend.py(Qt UI) andbackend.py(pure logic). - Settings schema: For segmentation/spots, keep
details.jsoncompatible withsrc/senoquant/utils/model_details.schema.json. - Model discovery:
- Segmentation/spots use
models/<name>/details.json+model.py. - Prediction uses
models/<name>/model.py(nodetails.jsonrequired). - Dataclasses: Use
@dataclass(slots=True)for config objects.
Naming conventions¶
- Segmentation outputs:
<image>_<model>_nuc_labelsor<image>_<model>_cyto_labels. - Spot outputs:
<image>_<detector>_spot_labels. - Private methods: Prefix with
_(for example,_compute_internal()). - Signals: Qt signals use past tense (for example,
segmentation_completedanderror_occurred).
Dependencies¶
Core dependencies¶
- napari: Not pinned in
pyproject.toml; install separately. - Qt: Via QtPy (supports PyQt5, PyQt6, PySide2, and PySide6).
- BioIO: Format-agnostic image reader with 50+ plugins.
- ONNX Runtime: For StarDist model inference.
Optional dependencies¶
Defined in pyproject.toml:
.[all]: Full stack including napari and optional dependencies.
Extending SenoQuant¶
Segmentation model¶
- Create folder:
src/senoquant/tabs/segmentation/models/my_model/. - Add metadata:
details.jsonwith model info, tasks, and settings. - Implement logic:
model.pysubclassingSenoQuantSegmentationModel. - Test: Verify the model appears in the Segmentation tab dropdown.
See Models & Detectors for the detailed guide.
Spot detector¶
Use the same pattern as segmentation models under src/senoquant/tabs/spots/models/.
Prediction model¶
- Create folder:
src/senoquant/tabs/prediction/models/my_model/. - Implement logic:
model.pysubclassingSenoQuantPredictionModel. - Provide UI hooks: implement
build_widget()+collect_widget_settings(). - Return layers: implement
run()to return napari-compatible layer specs.
See Prediction models for the detailed guide.
Quantification feature¶
- Create module:
src/senoquant/tabs/quantification/features/my_feature/. - Define data class: Subclass
FeatureDatafor configuration state. - Implement feature: Subclass
SenoQuantFeaturewithbuild()andexport()methods. - Register: Add to
FEATURE_DATA_FACTORYinfeatures/__init__.py. - Batch settings bundles: Update batch feature serialize/deserialize cases in
src/senoquant/tabs/batch/config.py.
See Quantification features for the detailed guide.
Visualization plot¶
- Create module:
src/senoquant/tabs/visualization/plots/my_plot.py. - Define plot class: Subclass
SenoQuantPlotwithplot_typeandorder. - Implement output: Write files in
plot(temp_dir, input_path, export_format, ...). - Register typed data: Add custom
PlotDataclass toPLOT_DATA_FACTORYwhen needed. - Test: Add handler and backend tests under
tests/senoquant/tabs/visualization/.
See Visualization tab for implementation details.
New tab¶
Create a new tab package under src/senoquant/tabs/, export it from src/senoquant/tabs/__init__.py, and wire it into src/senoquant/_widget.py.
See Adding tabs for the full wiring checklist.
Submitting changes¶
Pull request checklist¶
- [ ] Tests pass locally (
pytest). - [ ] Code follows style conventions.
- [ ] New features have test coverage.
- [ ] Documentation is updated (user docs, docstrings, and developer guides).
- [ ] No breaking changes to the batch config format (maintain backward compatibility).
Commit messages¶
Use descriptive commit messages.
Improve U-FISH spot detector threshold behavior
- Adjust threshold handling for edge cases.
- Update detector settings help text.
- Add regression tests for low-signal images.
Common pitfalls¶
- Protobuf version conflicts: Reinstall protobuf after TensorFlow when doing ONNX conversion.
- Headless testing:
conftest.pystubs handle missing Qt/napari; avoid top-level GUI imports in test files. - Model not discovered:
- Segmentation/Spots: check folder naming and confirm
details.jsonexists. - Prediction: check folder naming and confirm
model.pydefines aSenoQuantPredictionModelsubclass. - Batch quantification failures: Verify the
BatchViewershim has correct layer names.
Getting help¶
- GitHub issues: Report bugs or request features.
- Discussions: Ask questions or share use cases.
- Documentation: Consult the user and developer guides.
License¶
SenoQuant is released under the BSD 3-Clause License. By contributing, you agree to license your contributions under the same license.