Skip to content

Commit

Permalink
reviewing documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
IvoVellekoop committed Oct 11, 2024
1 parent fb7472b commit 161d482
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/source/conclusion.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ In this work we presented an open-source Python package for conducting and simul

OpenWFS incorporates features to reduce the chances of errors in the design of wavefront shaping code. Notably, the use of units of measure prevents the accidental mixing of units, and the automatic synchronization mechanism ensures that hardware is properly synchronized without the need to write any synchronization code. Finally, the ability to simulate full experiments, and to mock individual components, allows the user to test wavefront shaping algorithms without the need for physical hardware. We find this feature particularly useful since there is a lot that can go wrong in an experiment, (also see :cite:`Mastiani2024PracticalConsiderations`), and experimental issues and software issues are not always easy to distinguish. With OpenWFS, it is now possible to fully test the algorithms before entering the lab, which can save a lot of time and frustration.

We envision that OpenWFS will hold a growing collection of components for hardware control, advanced simulations, and wavefront shaping. Further expansion of the supported hardware is of high priority, especially wrapping c-based libraries and adding support for Micro-Manager device adapters. The standardised interfaces for detectors, actuators and SLMs will greatly simplify developing reusable code that can be used across different setups and experiments. The simulation tools may additionally be used for research and education, ushering in a new phase of applications in wavefront shaping. We therefore encourage the reader to join us in developing new algorithms and components for this framework.
We envision that OpenWFS will hold a growing collection of components for hardware control, advanced simulations, and wavefront shaping. Further expansion of the supported hardware is of high priority, especially wrapping C-based libraries and adding support for Micro-Manager device adapters. The standardised interfaces for detectors, actuators and SLMs will greatly simplify developing reusable code that can be used across different setups and experiments. The simulation tools may additionally be used for research and education, ushering in a new phase of applications in wavefront shaping. We therefore encourage the reader to join us in developing new algorithms and components for this framework.

Code availability
------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/source/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Actuators are devices that *move* things in the setup. This can be literal, such

Algorithms
------------
OpenWFS comes with a number of wavefront shaping algorithms already implemented, as listed in the table below. Although these algorithms could have been implemented as functions, we chose to implement them as objects, so that the parameters of the algorithm can be stored as attributes of the object. This simplifies keeping the parameters together in one place in the code, and also allows the algorithm parameters to be accessible in the Micro-Manager graphical user interface, see :ref:`section-micromanager`.
OpenWFS comes with a number of wavefront shaping algorithms already implemented, as listed in the table below. Although these algorithms could have been implemented as functions, we chose to implement them as objects, so that the parameters of the algorithm can be stored as attributes of the object. This simplifies keeping the parameters together in one place in the code, and also allows the algorithm parameters to be accessible in the Micro-Manager graphical user interface, see :numref:`section-micromanager`.

.. list-table::
:widths: 30 70
Expand Down
16 changes: 7 additions & 9 deletions docs/source/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ To download the source code, including tests and examples, clone the repository
poetry install --with dev --with docs
poetry run pytest
By default, this only installs the dependencies for the basic OpenWFS package. To install the dependencies for the other components (the OpenGL, genicam or nidaq), use ``poetry -E opengl -E genicam -E nidaq install`` or ``poetry -E all``

The examples are located in the ``examples`` directory. Note that a lot of functionality is also demonstrated in the automatic tests located in the ``tests`` directory. As an alternative to downloading the source code, the samples can also be copied directly from the example gallery on the documentation website :cite:`readthedocsOpenWFS`.

By default, this only installs the dependencies for the basic OpenWFS package. To install the dependencies for the other components (the OpenGL, genicam or nidaq), use ``poetry -E opengl -E genicam -E nidaq install`` or ``poetry -E all``.
.

Building the documentation
--------------------------------------------------
Expand All @@ -38,10 +40,7 @@ Note that for building the pdf version of the documentation, you need to have ``
make clean
make html
make markdown
make latex
cd _build/latex
xelatex openwfs
xelatex openwfs
tex
Reporting bugs and contributing
Expand All @@ -56,7 +55,7 @@ To implement a custom device (actuator, detector, processor), it is important to
- ``moving = True``. One or more actuators may be busy. No measurements can be made (none of the detectors is busy).
- ``moving = False`` (the 'measuring' state). One or more detectors may be busy. All actuators must remain static (none of the actuators is busy).

When an actuator is started, or when a detector is triggered, it calls ``self._start`` to request a switch to the correct global state. If a state switch is needed, this function blocks until all devices of the other device type are ready. For example, if an actuator calls ``_start``, the framework waits for all detectors to complete their measurements (up to latency, see :numref:`device-synchronization`) before the switch is made. Note that for detectors and processors, ``_start`` is called automatically by :meth:`~.Device.trigger()`, so there is never a need to call it explicitly.
When an actuator is started, or when a detector is triggered, it should call ``self._start`` to request a switch to the correct global state. If a state switch is needed, this function blocks until all devices of the other device type are ready. For example, if an actuator calls ``_start``, the framework waits for all detectors to complete their measurements (up to latency, see :numref:`device-synchronization`) before the switch is made. Note that for detectors and processors, ``_start`` is already called automatically by :meth:`~.Device.trigger()`, so there is no need to call it explicitly.


Implementing a detector
Expand All @@ -78,10 +77,9 @@ To implement an actuator, the user should subclass the :class:`~Actuator` base c

Implementing new algorithms
--------------------------------------------------
The algorithms that are included in OpenWFS are wrapped in classes with two common attribute: ``slm``, ``feedback``, which respectively hold a :class:`~.PhaseSLM` object to control the SLM and a :class:`~Detector` object that returns the feedback signals used in the optimization. For algorithms that support optimizing multiple targets simulaneously, the ``feedback`` detector may return an array of values.
The algorithms that are included in OpenWFS are implemented as classes with two common attribute: ``slm`` and ``feedback``, which respectively hold a :class:`~.PhaseSLM` object to control the SLM and a :class:`~Detector` object that returns the feedback signals used in the optimization. For algorithms that support optimizing multiple targets simulaneously, the ``feedback`` detector may return an array of values. As can be seen in the example in :numref:`hello-wfs`, OpenWFS abstracts all hardware interactions in the calls to ``slm.set_phases`` and ``feedback.trigger``, so the algorithm does not need to have any information on the nature of SLM or the origin of the feedback signal.
In addition, all algorithms have an ``execute()`` method that executes the algoritm and returns the measured transmission matrix, along with statistics about the measurements in a :class:`WFSResults` structure (see :numref:`section-troubleshooting`).
When implementing a new algorithm, it is perfectly acceptable to deviate from this convention. However, if an algorithm follows the convention described above, it can directly be wrapped in a `WFSController` so that it can be used in Micro-Manager (see :numref:`section-micromanager`)
As can be seen in the example in :numref:`hello-wfs`, OpenWFS abstracts all hardware interactions in the calls to ``slm.set_phases`` and ``feedback.trigger``.
When implementing a new algorithm, it is perfectly acceptable to deviate from this convention. However, if an algorithm follows the convention described above, it can directly be wrapped in a :class:`WFSController` so that it can be used in Micro-Manager (see :numref:`section-micromanager`).



Expand Down
2 changes: 1 addition & 1 deletion docs/source/micromanager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ An example of this integration can be found in the online example ``micro_manage

The OpenWFS microscope object loaded into Micro-Manager.

Beyond hardware components, the algorithms can also be controlled from Micro-Manager, as any Python object can be exposed. The :class:`WFSController` object in :class:`openwfs.algorithms.utilities` was made for this purpose. It allows the user to choose any algorithm, load it into Micro-Manager, and adjust settings from the GUI. Additionally, feedback on the performance of WFS algorithms is exposed, allowing the user to see parameters such as estimated enhancement and signal-to-noise ratio, and toggle the SLM to show the :class:`FLAT` or :class:`OPTIMIZED` wavefront. An example of this can be found in :class:`micro_manager_wfs.py` in the example gallery.
As any Python object can be exposed to Micro-Manager, this approach can also be used to control wavefront shaping algorithms from the GUI. The :class:`WFSController` object in :class:`openwfs.algorithms.utilities` was made for this purpose. It allows the user to load any algorithm into Micro-Manager, and adjust settings from the GUI. Additionally, feedback on the performance of WFS algorithms (see :numref:`section-troubleshooting`) is exposed, allowing the user to see parameters such as estimated enhancement and signal-to-noise ratio, and toggle the SLM to show the flat or optimized wavefront. An example of how to control a wavefront shaping algorithm in a fully simulated microscopy environment can be found in ``micro_manager_wfs.py`` in the example gallery.

0 comments on commit 161d482

Please sign in to comment.