https://github.com/user-attachments/assets/5744edc2-409e-4802-b06e-1972b8335a37
An 80-second tour — widefield, confocal/STED, and a custom super-resolution setup, all from one configuration.
Modular, configuration-driven microscope control — built for safety, testability, and AI-assisted development.
Imswitch2 is a Python application for flexible, modular microscope control. It supports a wide range of hardware — cameras, lasers, stages, DAQ cards, rotation mounts, pulse generators — through a configuration-driven manager system. Switching hardware means editing a JSON file, not the code.
This is a clean-slate continuation of the ImSwitch project, focused on safety, maintainability, and AI-assisted development under strict human oversight.
Features
|
42+ hardware managers out of the box — sCMOS cameras, photon counters, lasers, piezo stages, motorized rotators, FLIM time taggers, SLMs, microcontroller pulse generators. Pluggable architecture — every device type has an abstract base; adding a new driver is one new file + one entry in your setup JSON. Hardware-free dev mode — every manager has a documented mock fallback so you can develop, test, and configure without any device plugged in. |
Backend-agnostic pulse generation — drive lasers from a Swabian Pulse Streamer, a Teensy microcontroller, or future NI / FPGA backends through one common ABC. AI-assisted development workflow — agents are first-class contributors with clear guardrails, isolated branches, and mandatory human review. First-class documentation — Sphinx site with per-device JSON reference, task-oriented how-to guides, and a full architecture map. |
Quick start
Requires Python 3.10+ and PyQt5. Windows / macOS / Linux all supported.
# 1. Clone and install (core install — UI + file I/O, no hardware drivers)
git clone https://github.com/<your-fork>/Imswitch2.git
cd Imswitch2
pip install -e .
# 2. Launch
python -m imswitch
Imswitch2 creates ~/ImSwitchConfig/ on first launch and opens a setup-picker dialog. Pick one of the bundled example setups (e.g. example_no_hardware.json) to see the UI without any device connected.
The first launch is slow — give it a minute. Before the window appears, Imswitch2 creates its
~/ImSwitchConfig/folder structure and copies the example setups and scripts into it, and Python, napari and matplotlib build their caches. Later launches skip all of this and start much faster.
A fresh install loads three modules, one tab each down the left edge of the window: Hardware Control (ImControl, the microscope), Image Processing (ImProcess, reconstruction and analysis) and Scripting (ImScripting, the script editor). To change which ones load, use Preferences > Set active modules… or edit ~/ImSwitchConfig/config/modules.json. An existing modules.json is never overwritten, so a config folder from an older install keeps the modules it lists.
For real hardware:
pip install -e ".[hardware]" # NI-DAQ, Lantz, pyVISA
pip install -e ".[full]" # also napari, OpenCV, vispy
Documentation
The full documentation lives under docs/ and is rendered with Sphinx.
| Where | What you'll find |
|---|---|
docs/installation.rst |
Installation, dependencies, platform notes |
docs/gui.rst |
GUI tour with annotated screenshots |
docs/scripting.rst |
Scripting / API reference |
docs/devices/ |
Per-device JSON config reference — every manager, every field, with defaults |
docs/how-to/ |
Task-oriented guides — wire a Teensy, add a backend, port a driver, auto-screenshot widgets |
docs/design/ARCHITECTURE.md |
Full architecture map (managers, controllers, signal flow, startup) |
docs/design/plans/ |
Integration plans (active + historical) |
Build the docs locally
# One-off — install the doc toolchain
pip install sphinx sphinx-rtd-theme
# Build the HTML site
cd docs
sphinx-build -b html . _build/html
# Open it in your browser
# macOS: open _build/html/index.html
# Linux: xdg-open _build/html/index.html
# Windows: start _build/html/index.html
For a live-reloading dev server while editing docs:
pip install sphinx-autobuild
sphinx-autobuild docs docs/_build/html
# → serves at http://127.0.0.1:8000 and rebuilds on save
Regenerate screenshots
All widget screenshots under docs/images/auto/ are produced by a single script that launches Imswitch2 with the example_no_hardware.json setup and grabs each dock individually:
python tools/screenshot_widgets.py
See docs/how-to/auto-screenshots.rst for details and CI integration notes.
Hardware support
Imswitch2 ships managers for 42+ devices across five categories. Every manager has its JSON config field-by-field documented under docs/devices/.
| Detectors 13 managers |
Hamamatsu, Thorlabs TSI (Zelux/Kiralux/Quantalux), Photometrics, Basler, Daheng (GXPIPY), The Imaging Source, Raspberry Pi Cam, ESP32-Cam, Jetson, Swabian Time Tagger (FLIM), APD, PMT, generic OpenCV — see detectors.rst |
| Lasers 14 managers |
Cobolt (Lantz + direct serial variants), MPB, CoolLED, AAA AOTF, NI-DAQ analog, PulseStreamer, Teensy/Arduino pulse generator, ESP32 LED, LED matrix, Lantz-compatible, python-microscopy — see lasers.rst |
| Positioners 12 managers |
NI-DAQ analog (piezo / galvo), Physik Instrumente, Thorlabs Kinesis MLS203, Thorlabs BSC203, Piezoconcept Z (×2), Jena Z-piezo, Märzhäuser SCAN, Leica DMI, SmarACT, SQUID, mock — see positioners.rst |
| Rotators 3 managers |
Standa, Thorlabs Kinesis K10CR1, Thorlabs Elliptec ELL14/ELL14K (multidrop bus) — see rotators.rst |
| Other | NI-DAQ (scan + IO), Pulse Streamer, Teensy pulse generator, SLMs, recording (HDF5 / TIFF / Zarr), microscope stands (Leica DMI), ESP32 / SQUID / GRBL boards via RS232. |
Don't see your hardware? Adding a new driver is one file plus one JSON entry — see
docs/how-to/port-from-third-party.rstfor the canonical recipe, anddocs/adding-device-support.rstfor the abstract-base reference.
Configuration
Imswitch2 reads all hardware configuration from ~/ImSwitchConfig/:
~/ImSwitchConfig/ (Linux / macOS)
Documents\ImSwitchConfig\ (Windows)
├── config/
│ ├── imcontrol_options.json # active setup filename + recording folder
│ └── modules.json # which modules (tabs) load at startup
└── imcontrol_setups/
└── my_microscope.json # hardware definition
A GUI editor is included for building setup files without writing JSON by hand. Open it from a running ImSwitch under Tools > Edit hardware configuration..., or standalone without starting the microscope:
python utility_scripts/imswitch_config_editor.py
The editor loads built-in templates for every supported manager, lets you add and configure devices visually, and saves valid JSON directly into imcontrol_setups/.
Minimal setup file
A two-device setup (one synthetic camera -- AVManager serves mock frames, no video driver is bundled -- one Cobolt laser, no DAQ):
{
"detectors": {
"Camera": {
"managerName": "AVManager",
"managerProperties": {
"cameraListIndex": "mock",
"avcam": { "exposure": 100, "gain": 1 }
},
"analogChannel": null,
"digitalLine": null,
"forAcquisition": true
}
},
"lasers": {
"561 nm": {
"managerName": "Cobolt0601NewLaserManager",
"managerProperties": { "digitalPorts": ["COM4"] },
"analogChannel": null,
"digitalLine": null,
"wavelength": 561,
"valueRangeMin": 0,
"valueRangeMax": 200
}
},
"availableWidgets": ["Settings", "View", "Recording", "Image", "Laser"]
}
For per-field reference for every other manager's JSON shape, see docs/devices/.
Project structure
Imswitch2/
├── imswitch/ # Main package
│ ├── imcontrol/ # Hardware control module
│ │ ├── model/managers/ # One manager class per device type
│ │ ├── controller/ # Widget controllers + CommunicationChannel
│ │ ├── view/ # Qt widgets + napari viewer
│ │ └── _data/user_defaults/ # Example setup files
│ ├── imcommon/ # Shared framework (Qt layer, signals, logging)
│ ├── improcess/ # Post-acquisition processing module (was: imreconstruct)
│ └── imscripting/ # Scripting console module
├── utility_scripts/ # Config editor GUI + device templates
├── tools/ # Maintenance scripts (screenshots, codegen, …)
├── docs/ # Sphinx site (architecture, how-tos, device ref)
└── .github/workflows/ # CI pipeline
Deep dive: docs/design/ARCHITECTURE.md.
AI agent workflow
Imswitch2 uses AI agents as development assistants under strict human oversight:
GitHub Issue → Agent plans → Isolated branch/worktree → Tests → PR → Human review → Merge
- All agent code changes require human review — no automatic merges.
- Red-zone files (hardware timing, laser control, DAQ) require explicit maintainer approval.
- Agents work in isolated branches or worktrees; parallel agents don't share state.
- Every claim in the docs is grounded in source code — agents are explicitly forbidden from inventing fields, defaults, or vendor library calls.
See AGENTS.md for the full rules and templates.
Contributing
Contributions are very welcome — code, docs, hardware support, bug reports, use-case studies, all of it.
- See
CONTRIBUTING.mdfor the workflow and code-style expectations. - Project governance:
GOVERNANCE.md. - Community standards:
CODE_OF_CONDUCT.md.
Quick ways to help:
- Try Imswitch2 on your microscope and file a setup recipe.
- Report bugs with reproducible JSON setups attached.
- Improve docs — especially per-device cards under
docs/devices/. - Port a driver from a sibling project (see
docs/how-to/port-from-third-party.rst).
Citation
If you use Imswitch2 in your research, please cite the original ImSwitch JOSS paper:
@article{Casas-Moreno2021,
doi = {10.21105/joss.03394},
url = {https://doi.org/10.21105/joss.03394},
year = {2021},
publisher = {The Open Journal},
volume = {6},
number = {64},
pages = {3394},
author = {Xavier Casas Moreno and Staffan Al-Kadhimi and Jonatan Alvelid and Andreas Bodén and Ilaria Testa},
title = {ImSwitch: Generalizing microscope control in Python},
journal = {Journal of Open Source Software}
}
Acknowledgments & third-party code
Imswitch2 is a fork of ImSwitch, and builds on a lot of other people's work — vendored code (with its licences), projects we modelled our behaviour on (Fiji/ImageJ, Picasso, napari), and the papers behind the methods we implement.
See ACKNOWLEDGMENTS.md for the full list, and
licenses/ for third-party licence texts.
Parts of Imswitch2 were written with AI assistance, and standard image-processing routines have a limited number of sensible implementations — so some code may resemble other projects' even where it was written independently. If you believe your project is an uncredited source, please open an issue. We will add the attribution, or relicense or remove the code if there is a licence conflict.
License
GNU General Public License v3.0 — see LICENSE.
Third-party components retain their own licences — see
ACKNOWLEDGMENTS.md and licenses/.
Release files for imswitch2 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| imswitch2-0.2.0.tar.gz | 25.3 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| imswitch2-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.6 MB
Release files / imswitch2-0.2.0.tar.gz
| Download URL | imswitch2-0.2.0.tar.gz |
|---|---|
| Size | 25.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b55473a504c86df50d8d017287c2b28562a80e7401d2b415ef5c80ce5ea5404c
|
|
BLAKE2b-256 checksum How to use checksums |
3fdaa4c782910fdf9e4d008c33851199b906302048a333bb5f9bcf4c35770381
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / imswitch2-0.2.0-py3-none-any.whl
| Download URL | imswitch2-0.2.0-py3-none-any.whl |
|---|---|
| Size | 26.3 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dcd67a7a78e3f820111abf9ca91e6a932100178dce4440058ba3653b64754606
|
|
BLAKE2b-256 checksum How to use checksums |
308f295132fe4e550fd7c032d0aff4195b515274724c2f171fae82a5acab73f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log