diff --git a/.gitignore b/.gitignore
index 7bb5b41f..70c27dc9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,161 @@
-*.pyc
+# This gitignore file consists of 2 parts:
+# * The standard Python .gitignore rules from GitHub
+# * custom ignore rules for the labscript suite.
+#
+# These should be kept separate so that the generic rules can be updated with a
+# copy/paste without having to worry about whether we are removing custom rules
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
*.log
-*.orig
-*.aux
-*.toc
-dist/*
-*.egg-info
-*.eggs
\ No newline at end of file
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+.python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+#
+# Custom labscript suite .gitignore rules start below
+#
+
+# Editors
+.vscode/
+
+# conda build results
+conda_build/
+conda_packages/
+
+# Sphinx documentation
+docs/html/
+docs/source/_build/
+docs/source/components.rst
\ No newline at end of file
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 00000000..d0c3cbf1
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 00000000..9534b018
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css
new file mode 100644
index 00000000..d766bfa0
--- /dev/null
+++ b/docs/source/_static/custom.css
@@ -0,0 +1,63 @@
+/* Add space between collapsible details HTML tags */
+details {
+ margin-bottom: 1em;
+}
+
+/* Darker pygment highlighing of console input/output */
+.highlight .go {
+ color: #404040;
+}
+
+/* White captions in sidebar */
+.wy-nav-side p.caption {
+ color: #f5f5f5;
+}
+
+/* labscript blue, alpha = 83% */
+.wy-side-nav-search {
+ background: #2946bbd3;
+}
+
+.wy-nav-top {
+ background: #2946bbd3;
+}
+
+/* labscript green, alpha = 75% */
+.rst-content .note .admonition-title {
+ background: #00804fbf;
+}
+
+/* labscript green, alpha = 25% */
+.rst-content .note {
+ background: #00804f3f;
+}
+
+/* labscript red, alpha = 75% */
+.rst-content .warning .admonition-title {
+ background: #bc294cbf
+}
+
+/* labscript red, alpha = 25% */
+.rst-content .warning {
+ background: #bc294c3b;
+}
+
+/* Elevation
+*
+* Style box-shadows using Material Design's idea of elevation. These particular numbers are taken from here:
+*
+* https://github.com/material-components/material-components-web
+* https://material-components-web.appspot.com/elevation.html
+*/
+
+.rst-content img.screenshot {
+ border: none;
+ /* MD Elevation 8 */
+ box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2),
+ 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
+ margin-bottom: 24px;
+}
+
+img.labscript-suite-icon {
+ min-width: 32px;
+}
\ No newline at end of file
diff --git a/docs/source/_templates/components.rst b/docs/source/_templates/components.rst
new file mode 100644
index 00000000..f9669391
--- /dev/null
+++ b/docs/source/_templates/components.rst
@@ -0,0 +1,47 @@
+{% if current_project != 'the labscript suite' %}
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+
+ the labscript suite <{{intersphinx_mapping['labscript-suite'][0]}}>
+
+{% endif %}
+*labscript suite* components
+============================
+
+The *labscript suite* is modular by design, and is comprised of:
+
+.. list-table:: Python libraries
+ :widths: 10 90
+ :header-rows: 0
+
+ {% for prog, item in programs.items() if item.type == 'lib' %}
+ * - .. image:: {{img_path}}/{{item.icon}}
+ :target: {{intersphinx_mapping['%s' | format(prog)][0]}}
+ :class: labscript-suite-icon
+ - |{{prog}}|_ --- {{item.desc}}
+ {% endfor %}
+
+.. list-table:: Graphical applications
+ :widths: 10 90
+ :header-rows: 0
+
+ {% for prog, item in programs.items() if item.type == 'gui' %}
+ * - .. image:: {{img_path}}/{{item.icon}}
+ :target: {{intersphinx_mapping['%s' | format(prog)][0]}}
+ :class: labscript-suite-icon
+ - |{{prog}}|_ --- {{item.desc}}
+ {% endfor %}
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+
+ {% for prog in programs|sort if prog != current_project %}
+ {{prog}} <{{intersphinx_mapping['%s' | format(prog)][0]}}>
+ {% endfor %}
+
+{% for prog in programs %}
+.. |{{prog}}| replace:: **{{prog}}**
+.. _{{prog}}: {{intersphinx_mapping['%s' | format(prog)][0]}}
+{% endfor %}
\ No newline at end of file
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 00000000..d27dbccb
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,223 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+from pathlib import Path
+from m2r import MdInclude
+from recommonmark.transform import AutoStructify
+from jinja2 import FileSystemLoader, Environment
+
+# -- Project information (unique to each project) -------------------------------------
+
+project = "blacs"
+copyright = "2020, labscript suite"
+author = "labscript suite contributors"
+
+# The full version, including alpha/beta/rc tags
+from blacs import __version__ as version # noqa: E402
+
+release = version
+
+# HTML icons
+img_path = 'img'
+html_logo = img_path + "/blacs_64x64.svg"
+html_favicon = img_path + "/blacs.ico"
+
+# -- General configuration (should be identical across all projects) ------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ "sphinx.ext.autodoc",
+ "sphinx.ext.autosectionlabel",
+ "sphinx.ext.intersphinx",
+ "sphinx.ext.napoleon",
+ "sphinx.ext.todo",
+ "sphinx.ext.viewcode",
+ "sphinx_rtd_theme",
+ "recommonmark",
+]
+
+autodoc_typehints = 'description'
+
+# Prefix each autosectionlabel with the name of the document it is in and a colon
+autosectionlabel_prefix_document = True
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+# The suffix(es) of source filenames.
+source_suffix = ['.rst', '.md']
+
+# The master toctree document.
+master_doc = 'index'
+
+# intersphinx allows us to link directly to other repos sphinxdocs.
+# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html
+intersphinx_mapping = {
+ 'python': ('https://docs.python.org/3/', None),
+ 'numpy': ('https://numpy.org/doc/stable/', None),
+ 'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None),
+ 'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None),
+ 'qtutils': ('https://qtutils.readthedocs.io/en/stable/', None),
+ 'pyqtgraph': (
+ 'https://pyqtgraph.readthedocs.io/en/latest/',
+ None,
+ ), # change to stable once v0.11 is published
+ 'matplotlib': ('https://matplotlib.org/', None),
+ 'h5py': ('http://docs.h5py.org/en/stable/', None),
+ 'pydaqmx': ('https://pythonhosted.org/PyDAQmx/', None),
+ 'qt': (
+ '',
+ 'pyqt5-modified-objects.inv',
+ ) # from https://github.com/MSLNZ/msl-qt/blob/master/docs/create_pyqt_objects.py
+ # under MIT License
+ # TODO
+ # desktop-app
+ # spinapi/pynivision/etc
+}
+
+# list of all labscript suite components that have docs
+labscript_suite_programs = {
+ 'labscript': {
+ 'desc': 'Expressive composition of hardware-timed experiments',
+ 'icon': 'labscript_32nx32n.svg',
+ 'type': 'lib',
+ },
+ 'labscript-devices': {
+ 'desc': 'Plugin architecture for controlling experiment hardware',
+ 'icon': 'labscript_32nx32n.svg',
+ 'type': 'lib',
+ },
+ 'labscript-utils': {
+ 'desc': 'Shared modules used by the *labscript suite*',
+ 'icon': 'labscript_32nx32n.svg',
+ 'type': 'lib',
+ },
+ 'runmanager': {
+ 'desc': 'Graphical and remote interface to parameterized experiments',
+ 'icon': 'runmanager_32nx32n.svg',
+ 'type': 'gui',
+ },
+ 'blacs': {
+ 'desc': 'Graphical interface to scientific instruments and experiment supervision',
+ 'icon': 'blacs_32nx32n.svg',
+ 'type': 'gui',
+ },
+ 'lyse': {
+ 'desc': 'Online analysis of live experiment data',
+ 'icon': 'lyse_32nx32n.svg',
+ 'type': 'gui',
+ },
+ 'runviewer': {
+ 'desc': 'Visualize hardware-timed experiment instructions',
+ 'icon': 'runviewer_32nx32n.svg',
+ 'type': 'gui',
+ },
+}
+
+# whether to use stable or latest version
+labscript_suite_doc_version = os.environ.get('READTHEDOCS_VERSION', 'latest')
+if labscript_suite_doc_version not in ['stable', 'latest']:
+ labscript_suite_doc_version = 'stable'
+
+# add intersphinx references for each component
+for ls_prog in labscript_suite_programs:
+ intersphinx_mapping[ls_prog] = (
+ 'https://docs.labscriptsuite.org/projects/{}/en/{}/'.format(
+ ls_prog, labscript_suite_doc_version
+ ),
+ None,
+ )
+
+# add intersphinx reference for the metapackage
+if project != "the labscript suite":
+ intersphinx_mapping['labscript-suite'] = (
+ 'https://docs.labscriptsuite.org/en/{}/'.format(labscript_suite_doc_version),
+ None,
+ )
+
+# Make `some code` equivalent to :code:`some code`
+default_role = 'code'
+
+# hide todo notes if on readthedocs and not building the latest
+if os.environ.get('READTHEDOCS') and (
+ os.environ.get('READTHEDOCS_VERSION') != 'latest'
+ or (
+ os.environ.get('READTHEDOCS_PROJECT') == project
+ or os.environ.get('READTHEDOCS_PROJECT') == 'labscriptsuite'
+ )
+):
+ todo_include_todos = False
+else:
+ todo_include_todos = True
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = "sphinx_rtd_theme"
+html_title = "labscript suite | {project}".format(
+ project=project
+ if project != "labscript-suite"
+ else "experiment control and automation"
+)
+html_short_title = "labscript suite"
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Customize the html_theme
+html_theme_options = {'navigation_depth': 3}
+
+# Use m2r only for mdinclude and recommonmark for everything else
+# https://github.com/readthedocs/recommonmark/issues/191#issuecomment-622369992
+def setup(app):
+ config = {
+ # 'url_resolver': lambda url: github_doc_root + url,
+ 'auto_toc_tree_section': 'Contents',
+ 'enable_eval_rst': True,
+ }
+ app.add_config_value('recommonmark_config', config, True)
+ app.add_transform(AutoStructify)
+
+ # from m2r to make `mdinclude` work
+ app.add_config_value('no_underscore_emphasis', False, 'env')
+ app.add_config_value('m2r_parse_relative_links', False, 'env')
+ app.add_config_value('m2r_anonymous_references', False, 'env')
+ app.add_config_value('m2r_disable_inline_math', False, 'env')
+ app.add_directive('mdinclude', MdInclude)
+ app.add_stylesheet('custom.css')
+
+ # generate the components.rst file dynamically so it points to stable/latest
+ # of subprojects correctly
+ loader = FileSystemLoader(Path(__file__).resolve().parent / templates_path[0])
+ env = Environment(loader=loader)
+ template = env.get_template('components.rst')
+ with open(Path(__file__).resolve().parent / 'components.rst', 'w') as f:
+ f.write(
+ template.render(
+ intersphinx_mapping=intersphinx_mapping,
+ programs=labscript_suite_programs,
+ current_project=project,
+ img_path=img_path
+ )
+ )
diff --git a/docs/source/img/blacs.ico b/docs/source/img/blacs.ico
new file mode 100644
index 00000000..6f626d9d
Binary files /dev/null and b/docs/source/img/blacs.ico differ
diff --git a/docs/source/img/blacs_32nx32n.svg b/docs/source/img/blacs_32nx32n.svg
new file mode 100644
index 00000000..d6a2b0e3
--- /dev/null
+++ b/docs/source/img/blacs_32nx32n.svg
@@ -0,0 +1,178 @@
+
+
diff --git a/docs/source/img/blacs_64x64.svg b/docs/source/img/blacs_64x64.svg
new file mode 100644
index 00000000..f139a01d
--- /dev/null
+++ b/docs/source/img/blacs_64x64.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/docs/source/img/labscript_32nx32n.svg b/docs/source/img/labscript_32nx32n.svg
new file mode 100644
index 00000000..97272afa
--- /dev/null
+++ b/docs/source/img/labscript_32nx32n.svg
@@ -0,0 +1,186 @@
+
+
diff --git a/docs/source/img/lyse_32nx32n.svg b/docs/source/img/lyse_32nx32n.svg
new file mode 100644
index 00000000..1ddcdccd
--- /dev/null
+++ b/docs/source/img/lyse_32nx32n.svg
@@ -0,0 +1,256 @@
+
+
diff --git a/docs/source/img/runmanager_32nx32n.svg b/docs/source/img/runmanager_32nx32n.svg
new file mode 100644
index 00000000..d9df689a
--- /dev/null
+++ b/docs/source/img/runmanager_32nx32n.svg
@@ -0,0 +1,267 @@
+
+
diff --git a/docs/source/img/runviewer_32nx32n.svg b/docs/source/img/runviewer_32nx32n.svg
new file mode 100644
index 00000000..ee5aa68f
--- /dev/null
+++ b/docs/source/img/runviewer_32nx32n.svg
@@ -0,0 +1,223 @@
+
+
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 00000000..2993f86d
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,32 @@
+.. blacs documentation master file, created by
+ sphinx-quickstart on Thu Jun 18 17:05:42 2020.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+blacs
+=====
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+ :caption: DOCUMENTATION
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+ :caption: FURTHER DOCUMENTATION
+
+ components
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+ :caption: LINKS
+
+ Home Page
+ Source Code
+ PyPI
+ Anaconda Cloud
+ BitBucket Archive
+
+.. todolist::
diff --git a/readthedocs.yaml b/readthedocs.yaml
new file mode 100644
index 00000000..35084d6e
--- /dev/null
+++ b/readthedocs.yaml
@@ -0,0 +1,27 @@
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+ builder: dirhtml
+ configuration: docs/source/conf.py
+ fail_on_warning: false
+
+# Optionally build your docs in additional formats such as PDF
+formats:
+ - pdf
+ - epub
+
+# Optionally set the version of Python and requirements required to build your docs
+python:
+ version: 3.7
+ install:
+ - method: pip
+ path: .
+ extra_requirements:
+ - docs
+ system_packages: true
+
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
index 93e41b8f..6c871402 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -26,8 +26,8 @@ packages = find:
python_requires = >=3.6
install_requires =
importlib_metadata
- labscript_devices>=2.0
- labscript_utils>=2.15.0
+ labscript_devices>=3.0.0rc1
+ labscript_utils>=3.0.0rc1
qtutils>=2.3.2
zprocess>=2.14.1
@@ -39,3 +39,9 @@ gui_scripts =
[options.extras_require]
pyqt = PyQt5
+docs =
+ PyQt5
+ Sphinx==3.0.1
+ sphinx-rtd-theme==0.4.3
+ recommonmark==0.6.0
+ m2r==0.2.1