Skip to main content

Imswitch2 logo

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.

JOSS Python License: GPL v3


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

Two ways in: a ready-made installer, or pip.

Download a ready-made installer

Don't want to manage a Python environment? Every release ships a standalone build with Python and every dependency inside it — nothing else to install.

Download Size
Windows (64-bit) ImSwitch2-win64-setup.exe ~135 MB
macOS (Apple Silicon) ImSwitch2-macOS-arm64.dmg ~175 MB

Both links always point at the newest release. Three things to know before you click:

  • They are unsigned. Windows SmartScreen says "unrecognized app" — choose More info → Run anyway. macOS refuses to open it at all on first launch — right-click ImSwitch2 and choose Open. Nothing is wrong with the download; code-signing certificates cost money the project has not spent yet.
  • A bundled Imswitch2 cannot load pip-installed device plugins or vendor SDKs, and scripts in it can only import what was bundled. Great for analysis, teaching and trying it out; for a microscope, install with pip instead.
  • macOS is Apple Silicon only, and in practice macOS runs the analysis side — NI-DAQmx has no macOS support at all, and the Thorlabs and TIS camera SDKs are Windows/Linux only.

Having trouble, or want to build one yourself? See docs/packaging.rst.

Install with Python

Requires Python 3.10+ and PyQt5. Windows / macOS / Linux all supported.

pip install imswitch2, then run imswitch. This is the right choice for a microscope: a pip install can load device plugins and vendor SDKs, and a bundled one cannot.

Clone instead to develop on Imswitch2 itself, or for the newest fixes — PyPI releases trail main:

# 1. Clone and install (core install — UI + file I/O, no hardware drivers)
git clone https://github.com/Imswitch2/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. A modules.json you changed is kept when you update Imswitch2 (see Updates to the shipped files below).

For real hardware:

pip install -e ".[hardware]"   # NI-DAQ, Lantz, pyVISA
pip install -e ".[full]"       # also napari, OpenCV, vispy

Documentation

Offical Documentation on readthedocs


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.rst for the canonical recipe, and docs/adding-device-support.rst for 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

Updates to the shipped files. The example setups, the mock setups, the scripting tutorials and config/modules.json are copied into ~/ImSwitchConfig/ from the Imswitch2 package. At every start, a copy you have not edited that is an older shipped version is updated to the current one, and an untouched script Imswitch2 no longer ships is moved to the trash. Files you edited are never changed or removed; the log names the ones that differ from the current version -- delete one and restart to get the current version.

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.

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/.

Metadata

Release files for imswitch2 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for imswitch2 0.3.0
File Size Uploaded
imswitch2-0.3.0.tar.gz 25.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for imswitch2 0.3.0
File Interpreter ABI Platform
imswitch2-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 52.4 MB

Release files / imswitch2-0.3.0.tar.gz

Download URL imswitch2-0.3.0.tar.gz
Size 25.7 MB
Tags Source
SHA-256 checksum
How to use checksums
523017cca2c64187051b1b351303329564b6af9a9a39418aa1f1b183bf4cb63e
BLAKE2b-256 checksum
How to use checksums
c5f29a2f159a74076823e3af5966927d48d5c035431a7f85a06e2aa49010b9ea
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 Oct 4, 2026.

Transparency log

Release files / imswitch2-0.3.0-py3-none-any.whl

Download URL imswitch2-0.3.0-py3-none-any.whl
Size 26.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
9447e0d1817c4c9410ac7e15d6daea15f937e3e49fc818ca4ac7d3f2d1085af0
BLAKE2b-256 checksum
How to use checksums
88295b7ed4af825c14b9eb796747d88a5d5c74818bfa1d17c5d273d8cb2f7220
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 Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page