Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
bc525a1
Boiler plate doc files creation. Outlines basic documentation structure
dihm Oct 29, 2020
19e42fd
A few more updates to the Pylon Camera documentation and a start to the
dihm Oct 30, 2020
79a3e58
Increasing coverage to the rest of the devices, excluding a few remai…
dihm Oct 30, 2020
6ce351c
Adding boiler plate for rest of Pseudoclocks.
dihm Nov 4, 2020
0324995
Add docs for the SpinnakerCamera device I somehow overlooked.
dihm Nov 6, 2020
68d6837
Protecting the NI_DAQ.models.get_capabilities script against import.
dihm Nov 7, 2020
b5071bd
Add NI-DAQmx documentation.
dihm Nov 7, 2020
8215778
Fix some pathing issues on the last NI-DAQmx commit.
dihm Nov 7, 2020
e597a0a
Updating the NI_DAQmx model template and auto-generated files to produce
dihm Nov 7, 2020
7b0688f
Increasing doc details for flycapture2 and pylon cameras.
dihm Nov 13, 2020
30b983b
Adding some basic high-level documentation.
dihm Nov 13, 2020
5567a9d
Updated doc string in conf.py
dihm Dec 29, 2020
75bcb30
Updated usage documentation for Spinnaker cameras.
dihm Dec 29, 2020
c7a4f58
Fix apidoc auto-run code.
dihm May 27, 2021
45a54ed
Adding unlisted dependencies so doc builds can successfully import more
dihm May 27, 2021
b8e7923
Sphinx version bump to match necessary bumps in other labscript docs.
dihm May 27, 2021
a78ed95
Modify Spinnaker Camera so proprietary PySpin import does not happen on
dihm May 27, 2021
82871bc
Attempting the easy mocking provided within sphinx-autodoc to mock al…
dihm May 27, 2021
3a2087f
Basic high-level docs for the new PrawnBlaster device.
dihm May 31, 2021
69a7a47
Update sphinx_rtd_theme pin to 0.5.2 and fix PrawnBlaster nested list…
dihm May 31, 2021
ab577ba
Yet another tweak of the Prawnblaster bullet list.
dihm May 31, 2021
40b9a0c
Fix warning in pylon.rst
dihm May 31, 2021
17c507f
Actually get automodule to document the PrawnBlaster code.
dihm May 31, 2021
436f330
Add docstring-level documentation for the new PrawnBlaster pseudocloc…
dihm Jun 1, 2021
34751ce
Add PyQT5 intersphinx inventory.
dihm Jun 1, 2021
20c2b6d
Improve NI-DAQmx docs a little.
dihm Jul 12, 2021
c554131
Add docstring coverage to build.
dihm Jul 15, 2021
d9514f0
Update sphinx version.
dihm Jul 15, 2021
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,4 @@ conda_packages/
docs/html/
docs/source/_build/
docs/source/components.rst
docs/source/devices/_apidoc
47 changes: 47 additions & 0 deletions docs/source/_templates/models/package.rst_t
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{%- macro automodule(modname, options) -%}
.. automodule:: {{ modname }}
{%- for option in options %}
:{{ option }}:
{%- endfor %}
{%- endmacro %}

{%- macro toctree(docnames) -%}
.. toctree::
:maxdepth: {{ maxdepth }}
{% for docname in docnames %}
{{ docname }}
{%- endfor %}
{%- endmacro %}

{%- macro autosummary(submodules) -%}
.. autosummary::
{% for submodule in submodules %}
{{submodule}}
{%- endfor %}
{%- endmacro %}

{%- macro autosum(pkgname) -%}
.. autosummary::

{{pkgname}}
{%- endmacro %}

{%- if is_namespace %}
{{- [pkgname, "namespace"] | join(" ") | e | heading }}
{% else %}
{# {{- [pkgname, ""] | join(" ") | e | heading }} #}
{% endif %}

{%- if submodules %}
{{ autosummary(submodules) }}
{% if separatemodules %}
{{ toctree(submodules) }}
{% else %}
{%- for submodule in submodules %}
{% if show_headings %}
{{- [submodule, ""] | join(" ") | e | heading(2) }}
{% endif %}
{{ automodule(submodule, automodule_options) }}
{% endfor %}
{%- endif %}
{%- endif %}
59 changes: 59 additions & 0 deletions docs/source/adding_devices.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
How to Add a Device
===================

Adding a **labscript-device** involves implementing interfaces for your hardware to different protions of the **labscript-suite**. Namely, you must provide

* A `labscript_device` that takes **labscript** high-level commands and turns them into instructions that are saved to the shot h5 file.
* A `BLACS_worker` that handles communication with the hardware, in particular interpreting the instructions from the shot h5 file into the necessary hardware commands to configure the device.
* A `BLACS_tab` which provides a graphical interface to control the instrument via **BLACS**

Though not strictly required, you should also consider providing a `runviewer_parser`, which can read the h5 instructions and produce the appropriate shot timings that would occur. This interface is only used in **runviewer**.

General Strategy
~~~~~~~~~~~~~~~~

As a general rule, it is best to model new hardware implementations off of a currently implemented device that has similar functionality. If the functionality is similar enough, it may even be possible to simply sub-class the currently implemented device, which is likely preferrable.

Barring the above simple solution, one must work from scratch. It is best to begin by determining the **labscript** device class to inherit from: `Psuedoclock`, `Device`, `IntermediateDevice`. The first is for implementing Psuedoclock devices, the second is for generic devices that are not hardware timed by a pseudoclock, and the last is for hardware timed device that are connected to another device controlled via labscript.

The `labscript_device` implements general configuration parameters, many of which are passed to the `BLACS_worker`. It also implements the `generate_code` method which converts **labscript** high-level instructions and saves them to the h5 file.

The `BLACS_tab` defines the GUI widgets that control the device. This typically takes the form of using standard widgets provided by **labscript** for controlling **labscript** output primitives (ie `AnalogOut`, `DigitalOut`,`DDS`, etc). This configuration is done in the `initialiseGUI` method. This also links directly to the appropriate BLACS workers.

The `BLACS_worker` handles communication with the hardware itself and often represents the bulk of the work required to implement a new labscript device. In general, it should provide five different methods:

* `init`: This method initialised communications with the device. Not to be confused with the standard python class `__init__` method.
* `program_manual`: This method allows for user control of the device via the `BLACS_tab`, setting outputs to the values set in the `BLACS_tab` widgets.
* `check_remote_values`: This method reads the current settings of the device, updating the `BLACS_tab` widgets to reflect these values.
* `transition_to_buffered`: This method transitions the device to buffered shot mode, reading the shot h5 file and taking the saved instructions from `labscript_device.generate_code` and sending the appropriate commands to the hardware.
* `transition_to_manual`: This method transitions the device from buffered to manual mode. It does any necessary configuration to take the device out of buffered mode and is used to read an measurements and save them to the shot h5 file as results.

The `runviewer_parser` takes shot h5 files, reads the saved instructions, and allows you to view them in **runviewer** in order to visualise experiment timing.

Code Organization
~~~~~~~~~~~~~~~~~

There are currently two supported file organization styles for a labscript-device.

The old style has the `labscript_device`, `BLACS_tab`, `BLACS_worker`, and `runviewer_parser` all in the same file, which typically has the same name as the `labscript_device` class name.

The new style allows for arbitrary code organization, but typically has a folder named after the `labscript_device` with each device component in a different file (ie `labscript_devices.py`, `BLACS_workers.py`, etc). With this style, the folder requires an `__init__.py` file (which can be empty) as well as a `register_classes.py` file. This file imports :ref:`<labscript-utils/device_registry>` via

.. code-block:: python

from labscript_devices import register_classes

This function informs **labscript** where to find the necessary classes during import. An example for the `NI_DAQmx` device is

.. code-block:: python

register_classes(
'NI_DAQmx',
BLACS_tab='labscript_devices.NI_DAQmx.blacs_tabs.NI_DAQmxTab',
runviewer_parser='labscript_devices.NI_DAQmx.runviewer_parsers.NI_DAQmxParser',
)

Contributions to **labscript-devices**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you decide to implement a labscript-device for controlling new hardware, we highly encourage you to consider making a pull-request to the **labscript-devices** repository in order to add your work to the **labscript-suite**. Increasing the list of supported devices is an important way for the **labscript-suite** to continue to grow, allowing new users to more quickly get up and running with hardware they may already have.
64 changes: 64 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.autosectionlabel",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
Expand All @@ -49,6 +50,8 @@
]

autodoc_typehints = 'description'
autoclass_content = 'both' # options: 'both', 'class', 'init'
autodoc_mock_imports = ['PyDAQmx']

# Prefix each autosectionlabel with the name of the document it is in and a colon
autosectionlabel_prefix_document = True
Expand Down Expand Up @@ -223,3 +226,64 @@ def setup(app):
img_path=img_path
)
)

# hook to run apidoc before building
app.connect('builder-inited', run_apidoc)
# hooks to test docstring coverage
app.connect('autodoc-process-docstring', doc_coverage)
app.connect('build-finished', doc_report)


def run_apidoc(_):
"""Runs apidoc with our desired parameters to generate the NI_DAQmx models docs.
"""
from sphinx.ext.apidoc import main
if os.environ.get('READTHEDOCS'):
rel_path = '../..'
else:
rel_path = '..'
daq_models_path = os.path.join(os.path.abspath(rel_path),
'labscript_devices')
out_path = os.path.join(os.path.dirname(Path(__file__)),
'devices', '_apidoc', 'models')
templates_path = os.path.join(os.path.dirname(Path(__file__)),
'_templates', 'models')
main(['-TMf', '-s', 'inc',
'-t', templates_path,
'-o', out_path, daq_models_path])


members_to_watch = ['module', 'class', 'function', 'exception', 'method', 'attribute']
doc_count = 0
undoc_count = 0
undoc_objects = []
undoc_print_objects = False


def doc_coverage(app, what, name, obj, options, lines):
global doc_count
global undoc_count
global undoc_objects

if (what in members_to_watch and len(lines) == 0):
# blank docstring detected
undoc_count += 1
undoc_objects.append(name)
else:
doc_count += 1


def doc_report(app, exception):
global doc_count
global undoc_count
global undoc_objects
# print out report of documentation coverage
total_docs = undoc_count + doc_count
if total_docs != 0:
print(f'\nAPI Doc coverage of {doc_count/total_docs:.1%}')
if undoc_print_objects or os.environ.get('READTHEDOCS'):
print('\nItems lacking documentation')
print('===========================')
print(*undoc_objects, sep='\n')
else:
print('No docs counted, run \'make clean\' then rebuild to get the count.')
85 changes: 85 additions & 0 deletions docs/source/devices.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
Devices
=========

Here is a list of all the currently supported devices.


Pseudoclocks
~~~~~~~~~~~~

Pseudoclocks provide the timing backbone of the labscript_suite. These devices produce hardware-timed clocklines that trigger other device outputs and acquisitions. Many pseudoclock devices also include other types of outputs, including digital voltage and DDS frequency synthesizers.

.. toctree::
:maxdepth: 2

devices/pulseblaster
devices/pulseblaster_no_dds
devices/opalkellyXEM3001
devices/pineblaster
devices/prawnblaster
devices/rfblaster

NI DAQS
~~~~~~~~~~~~

The NI_DAQmx device provides a generic interface for National Instruments data acquisition hardware. This includes digital and analog voltage I/O. These input/outputs can be either static or hardware-timed dynamically changing variables.

.. toctree::
:maxdepth: 2

devices/ni_daqs

Cameras
~~~~~~~~~~~~

The camera devices provide interfaces for using various scientific cameras to acquire hardware-timed images during an experiment. They are organized by the programming API the underlies the communication to the device. The "master" camera class which provides the core functionality and from which the others derive is the IMAQdx class.

.. toctree::
:maxdepth: 2

devices/IMAQdx
devices/pylon
devices/flycapture2
devices/spinnaker
devices/andorsolis


Frequency Sources
~~~~~~~~~~~~~~~~~

These devices cover various frequency sources that provide either hardware-timed frequency, amplitude, or phase updates or static frequency outputs.

.. toctree::
:maxdepth: 2

devices/novatechDDS9m
devices/phasematrixquicksyn


Miscellaneous
~~~~~~~~~~~~~~~

These devices cover other types of devices.

.. toctree::
:maxdepth: 2

devices/alazartechboard
devices/lightcrafterdmd
devices/tekscope
devices/zaberstagecontroller


Other
~~~~~~~~~~~~~~

These devices provide dummy instruments for prototyping and testing purposes of the rest of the labscript_suite as well as the FunctionRunner device which can run arbitrary code post-shot.

.. toctree::
:maxdepth: 2

devices/functionrunner
devices/dummypseudoclock
devices/dummyintermediate
devices/testdevice

47 changes: 47 additions & 0 deletions docs/source/devices/IMAQdx.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
IMAQdx Cameras
==============

Overview
~~~~~~~~

The "master" camera device from which all others derive.

.. autosummary::
labscript_devices.IMAQdxCamera.labscript_devices
labscript_devices.IMAQdxCamera.blacs_tabs
labscript_devices.IMAQdxCamera.blacs_workers

Installation
~~~~~~~~~~~~


Usage
~~~~~


Detailed Documentation
~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: labscript_devices.IMAQdxCamera
:members:
:undoc-members:
:show-inheritance:
:private-members:

.. automodule:: labscript_devices.IMAQdxCamera.labscript_devices
:members:
:undoc-members:
:show-inheritance:
:private-members:

.. automodule:: labscript_devices.IMAQdxCamera.blacs_tabs
:members:
:undoc-members:
:show-inheritance:
:private-members:

.. automodule:: labscript_devices.IMAQdxCamera.blacs_workers
:members:
:undoc-members:
:show-inheritance:
:private-members:
22 changes: 22 additions & 0 deletions docs/source/devices/alazartechboard.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Alazar Tech Board
=================

A labscript device class for data acquisition boards made by Alazar Technologies Inc (ATS).

Installation
~~~~~~~~~~~~

This device requires the atsapi.py wrapper. It should be installed into site-packages or
kept in the local directory.

It also uses the tqdm progress bar, which is not a standard dependency for the labscript-suite.

Detailed Documentation
~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: labscript_devices.AlazarTechBoard
:members:
:undoc-members:
:show-inheritance:
:member-order: bysource
:private-members:
Loading