Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
947c1b2
Refactor device base classes to use ABC and abstract methods
AdvancedImagingUTSW Sep 16, 2025
431d98e
Camera Abstract Base Class
AdvancedImagingUTSW Sep 16, 2025
1b4f626
Refactor device base classes to use ABC and abstract methods
AdvancedImagingUTSW Sep 26, 2025
b67ae55
Update synthetic.py
AdvancedImagingUTSW Sep 26, 2025
82b4394
Update Developer Documentation
AdvancedImagingUTSW Sep 28, 2025
d4a1930
Refactor StageBase to use abstract base class
AdvancedImagingUTSW Sep 28, 2025
6e20683
Add synthetic device methods and type annotations
AdvancedImagingUTSW Sep 28, 2025
3380d36
Refactor tests to use synthetic device classes
AdvancedImagingUTSW Sep 28, 2025
9419d8e
Update test_stage_base.py
AdvancedImagingUTSW Sep 29, 2025
71a599b
Update test_stage_base.py
AdvancedImagingUTSW Sep 29, 2025
1f1f4c4
tweak camera classes
annie-xd-wang Sep 29, 2025
601065b
tweak daq classes
annie-xd-wang Sep 30, 2025
f95acd2
tweak filter wheel classes
annie-xd-wang Sep 30, 2025
291c46e
tweak galvo classes
annie-xd-wang Sep 30, 2025
aea9a30
tweak laser classes
annie-xd-wang Sep 30, 2025
5146c8b
tweak remote focus classes
annie-xd-wang Sep 30, 2025
09866a5
tweak shutter classes
annie-xd-wang Sep 30, 2025
606afe4
tweak stage classes
annie-xd-wang Sep 30, 2025
26d58d2
tweak zoom classes
annie-xd-wang Sep 30, 2025
3501ec9
small tweaks
annie-xd-wang Sep 30, 2025
53018ad
Merge branch 'develop' into abstract_base_classes
AdvancedImagingUTSW Oct 1, 2025
581421b
Merge branch 'abstract_base_classes' of https://github.com/TheDeanLab…
AdvancedImagingUTSW Oct 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
.. _contributing_guidelines:

=======================
************************
Contributing Guidelines
************************

.. contents:: Table of Contents
:depth: 3

General Overview
=======================

We welcome contributions in the form of bug reports, bug fixes, new features and documentation. If you are contributing code, please create it in a fork and branch separate from the main ``develop`` branch and then make a pull request to the ``develop`` branch for code review. Some best practices for new code are outlined below.
We welcome contributions in the form of bug reports, bug fixes, new features and documentation. Some best practices for contributing code are outlined below. If you are considering refactoring the code, please reach out to us prior to starting this process.

If you are considering refactoring part of the code, please reach out to us prior to starting this process. We are happy to invite you to our regular software development meeting.
-------------------

Project Philosophy
==================

**navigate** is designed with the following principles in mind:

* Prioritize standard library imports for maximum stability, and minimize external dependencies.
* Abstraction layer to drive different camera types, etc.
* Plugin architecture for extensibility.
* Maximize productivity for biological users through robust graphical user interface-based workflows.
* Performant and responsive.
* Brutally obvious, well-documented, clean code organized in an industry standard Model-View-Controller architecture.

We ask that all contributions adhere to these principles.

-------------------

Expand All @@ -17,45 +37,64 @@ General Principles
- Please do not create new configuration variables unless absolutely necessary, especially in the ``configuration.yaml`` and ``experiment.yaml`` files. A new variable is necessary only if no variable stores similar information or there is no way to use the most similar variable without disrupting another part of the code base.
- We are happy to discuss code refactors for improved clarity and speed. However, please do not modify something that is already working without discussing this with the software team in advance.
- All code that modifies microscope control behavior must be reviewed and tested on a live system prior to merging into the ``develop`` branch.
- Scientific Units - Please express quantities in the following units when they are in the standard model/view/controller code. Deviations from this can occur where it is necessary to pass a different unit to a piece of hardware.

-------------------
* Time - Milliseconds
* Distance - Micrometers
* Voltage - Volts
* Rotation - Degrees

Coding Style
============

We follow the `PEP8 code style guide <https://peps.python.org/pep-0008/>`_. All class names are written in ``CamelCase`` and all variable names are ``lowercase_and_separated_by_underscores``.

-------------------

Communicating with Hardware
===========================
Getting Started
==============

In handling hardware devices, such as Sutter's MP-285A stage, using threads can introduce complexities, especially when simultaneous read and write operations occur over a shared resource like a serial line. An encountered issue demonstrated the challenges when two different threads attempted to write to and read from the same serial port simultaneously. This action led to data corruption due to interleaving of read/write calls that require precise handshaking, characteristic of the MP-285A's communication protocol. The solution involved implementing a blocking mechanism using `threading.Event()` to ensure that operations on the serial port do not overlap, showcasing the difficulties of multithreading sequential processes. To mitigate such issues, a design where each hardware device operates within its own dedicated thread is advisable. This approach simplifies the management of device communications by enforcing sequential execution, eliminating the need to handle complex concurrency issues inherent in multithreading environments. This strategy ensures robust and error-free interaction with hardware devices.
1. **Fork and Clone**: Fork the repository and clone it locally
2. **Set Up Environment**: `pip install -e .[dev]` to install in development mode
3. **Install Pre-commit Hooks**: `pre-commit install` to set up linting hooks
4. **Run Tests**: Ensure `pytest` passes before making changes

-------------------

Documentation
=============
Pull Request Process
===================

1. Create a branch from `develop` with a descriptive name
2. Make your changes following the guidelines in this document
3. Add tests for new functionality
4. Ensure all tests pass and linting is clean
5. Update documentation as needed
6. Submit PR to the `develop` branch with clear description of changes

We use `Sphinx <https://www.sphinx-doc.org/en/master/>`_ to generate documentation from documented methods, attributes, and classes. Please document all new methods, attributes, and classes using a Sphinx compatible version of `Numpydoc <https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html>`_.

-------------------

Scientific Units
================
Coding Style
============

Naming Conventions
------------------
We follow the `PEP8 code style guide <https://peps.python.org/pep-0008/>`_. All class names are written in ``CamelCase`` and all variable names are ``lowercase_and_separated_by_underscores``.

Please express quantities in the following units when they are in the standard model/view/controller code. Deviations from this can occur where it is necessary to pass a different unit to a piece of hardware.
Type Hints
----------------
Type hints are used throughout the code base. Please add type hints to any new methods or functions you create. If you are unsure how to do this, please see `PEP 484 <https://peps.python.org/pep-0484/>`_ for more information.

* Time - Milliseconds
* Distance - Micrometers
* Voltage - Volts
* Rotation - Degrees
Numpydoc
----------------
We use `Numpydoc <https://numpydoc.readthedocs.io/en/latest/format.html>`_ style docstrings throughout the code base. Please use this style for any new methods or functions you create.

-------------------
Sphinx
----------------
We use `Sphinx <https://www.sphinx-doc.org/en/master/>`_ to generate documentation from documented methods, attributes, and classes. Please document all new methods, attributes, and classes using a Sphinx compatible version of `Numpydoc <https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html>`_.

Pre-Commit Hooks
================
Linters
----------------
We use `Ruff <https://docs.astral.sh/ruff/>`_ to enforce consistent code formatting. Please run Ruff on your code before making a pull request. Ideally, these actions should be integrated as part of a pre-commit hook (see below).

Pre-commit Hooks
----------------
We use `pre-commit hooks <https://pre-commit.com/>`_ to enforce consistent code formatting and automate some of the code review process. In some rare cases, the linter may complain about a line of code that is actually fine. For example, in the example code below, Ruff linter complains that the start_stage class is imported but not used. However, it is actually used in as part of an ``exec`` statement.

.. code-block:: python
Expand All @@ -70,11 +109,12 @@ To avoid this error, add a ``# noqa`` comment to the end of the line to tell Ruf

from navigate.model.device_startup_functions import start_stage # noqa

-------------------
Unit Tests
----------------
Each line of code is unit tested to ensure it behaves appropriately and alert future coders to modifications that break expected functionality. Guidelines for writing good unit tests can be found `here <https://stackoverflow.com/questions/61400/what-makes-a-good-unit-test>`_ and `over here <https://medium.com/chris-nielsen/so-whats-a-good-unit-test-look-like-71f750333ac0>`_, or in examples of unit tests in this repository's ``test`` folder. We use the `pytest library <https://docs.pytest.org/en/7.2.x/>`_ to evaluate unit tests. Please check that unit tests pass on your machine before making a pull request.

Dictionary Parsing
==================

------------------
The :ref:`configuration file <configuration_file>` is loaded as a large dictionary object, and it is easy to create small errors in the dictionary that can crash the program. To avoid this, when getting properties from the configuration dictionary, it is best to use the ``.get()`` command, which provides you with the opportunity to also have a default value should the key provided not be found. For example,

.. code-block:: python
Expand All @@ -86,35 +126,47 @@ Here, we try to retrieve the ``waveform`` key from a the ``self.device_config``

-------------------

Unit Tests
==========
Communicating with Hardware
===========================

Each line of code is unit tested to ensure it behaves appropriately and alert future coders to modifications that break expected functionality. Guidelines for writing good unit tests can be found `here <https://stackoverflow.com/questions/61400/what-makes-a-good-unit-test>`_ and `over here <https://medium.com/chris-nielsen/so-whats-a-good-unit-test-look-like-71f750333ac0>`_, or in examples of unit tests in this repository's ``test`` folder. We use the `pytest library <https://docs.pytest.org/en/7.2.x/>`_ to evaluate unit tests. Please check that unit tests pass on your machine before making a pull request.
Threads and Blocking
---------------------------
In handling hardware devices, such as Sutter's MP-285A stage, using threads can introduce complexities, especially when simultaneous read and write operations occur over a shared resource like a serial line. An encountered issue demonstrated the challenges when two different threads attempted to write to and read from the same serial port simultaneously. This action led to data corruption due to interleaving of read/write calls that require precise handshaking, characteristic of the MP-285A's communication protocol. The solution involved implementing a blocking mechanism using `threading.Event()` to ensure that operations on the serial port do not overlap, showcasing the difficulties of multithreading sequential processes. To mitigate such issues, a design where each hardware device operates within its own dedicated thread is advisable. This approach simplifies the management of device communications by enforcing sequential execution, eliminating the need to handle complex concurrency issues inherent in multithreading environments. This strategy ensures robust and error-free interaction with hardware devices.

-------------------

Developing with a Mac
=====================
Dedicated Device Interfaces
---------------------------

Many of us have Apple products and use them for development. However, there are some issues that you may encounter when developing on a Mac. Below are some of the issues we have encountered and how to resolve them.
**navigate** implements a robust hardware abstraction layer through dedicated device interfaces. When integrating new hardware devices:

-------------------
* Each hardware device type (cameras, stages, etc.) has its own dedicated interface that must be implemented
* All hardware classes inherit from a base class specific to the device type
* Base classes include AbstractMethods that define the required interface for any derived hardware class
* These abstract methods clearly communicate which functions must be implemented for any new hardware
* Failure to override these abstract methods in derived classes will result in runtime errors

This architecture ensures consistency across different hardware implementations while providing clear guidance for developers adding support for new devices. When adding support for a new hardware device, first identify the appropriate base class and ensure you implement all required abstract methods.




.. Developing with a Mac
.. =====================

Shared memory limits
^^^^^^^^^^^^^^^^^^^^
.. Many of us have Apple products and use them for development. However, there are some issues that you may encounter when developing on a Mac. Below are some of the issues we have encountered and how to resolve them.

.. code-block:: console
.. .. code-block:: console

OSError: You tried to simultaneously open more SharedNDArrays than are allowed by your system!
.. OSError: You tried to simultaneously open more SharedNDArrays than are allowed by your system!

This results from a limitation in the number of shared memory objects that can be created on a Mac. To figure out how many objects can open, open a terminal and run the following command
.. This results from a limitation in the number of shared memory objects that can be created on a Mac. To figure out how many objects can open, open a terminal and run the following command

.. code-block:: console
.. .. code-block:: console

ulimit -n
.. ulimit -n

To increase this number, simply add an integer value after it. In our hands, 1000 typically works:
.. To increase this number, simply add an integer value after it. In our hands, 1000 typically works:

.. code-block:: console
.. .. code-block:: console

ulimit -n 1000
.. ulimit -n 1000
46 changes: 32 additions & 14 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,36 @@
**navigate**
############

.. image:: https://img.shields.io/badge/Published%20in-Nature%20Methods-blue
:target: https://doi.org/10.1038/s41592-024-02413-4
:alt: Published in Nature Methods

**navigate** is an open-source Python software for light-sheet microscope control. It focuses on smart microscopy applications by providing reusable acquisition and analysis routines, termed :ref:`features <features>`, that can be chained in arbitrary orders to create custom acquisition protocols. **navigate** is designed to accommodate the needs of a diverse user base, from biologists with no programming experience to advanced technology developers.
.. image:: https://img.shields.io/github/stars/TheDeanLab/navigate?style=social
:target: https://github.com/TheDeanLab/navigate
:alt: GitHub Stars

**Project Philosophy**
=========================
.. image:: https://img.shields.io/pypi/v/navigate-micro
:target: https://pypi.org/project/navigate-micro/
:alt: PyPI Version

* Prioritize standard library imports for maximum stability, and minimize external dependencies.
* Abstraction layer to drive different camera types, etc.
* Plugin architecture for extensibility.
* Maximize productivity for biological users through robust graphical user interface-based workflows.
* Performant and responsive.
* Brutally obvious, well-documented, clean code organized in an industry standard Model-View-Controller architecture.
.. image:: https://img.shields.io/pypi/pyversions/navigate-micro
:target: https://pypi.org/project/navigate-micro/
:alt: Python Versions

.. note::

**navigate** is an open-source Python software for light-sheet microscope control. It focuses on smart microscopy applications by providing reusable acquisition and analysis routines, termed :ref:`features <features>`, that can be chained together arbitrarily to create custom acquisition protocols. **navigate** is accompanied by `Altair <https://thedeanlab.github.io/altair/>`_, our open-source light-sheet microscope designs. **navigate** is designed to accommodate the needs of a diverse user base, from biologists with no programming experience to advanced technology developers.

**Key Features**
================

- Smart microscopy control with customizable acquisition protocols
- Hardware abstraction layer supporting multiple device vendors
- Intuitive GUI for biologists with no programming experience
- Extensible plugin architecture for developers
- Integration with open-source light-sheet microscope designs


.. seealso::

This project is under active development. See our `GitHub repository for updates <https://github.com/TheDeanLab/navigate>`_.

Expand Down Expand Up @@ -87,13 +103,15 @@

**Authors**
============
**navigate** includes key contributions from numerous individuals, both past and present, in `The Dean Lab <https://www.dean-lab.org>`_. Please see the accompanying manuscript for a full list of contributors. :ref:`Outside contributors <contributing_guidelines>` are welcome.

**navigate** includes key contributions from individuals both inside and outside of `The Dean Lab <https://www.dean-lab.org>`_. Please see the GtiHub repository for a full list of contributors. We welcome community contributions - see our :ref:`contributing guidelines <contributing_guidelines>` for more information on how to get involved.


**Funding**
============
**navigate** is supported by the

- Cancer Prevention and Research Institute of Texas (10068451).
- NIH National Institute of General Medical Science (RM1GM145399).
- NIH National Cancer Institute (1U54CA268072).
- `Simmons Comprehensive Cancer Center <https://www.utsouthwestern.edu/departments/simmons/>`_ Translational Seed Grant.
- `UTSW President's Research Council <https://engage.utsouthwestern.edu/pages/membership-giving/membership-giving---presidents-research-council>`_
- Simmons Comprehensive Cancer Center Translational Seed Grant.
- UTSW President's Research Council
Loading