https://github.com/pymmcore-plus/pymmdevice
Direct Python wrapper for MMDevice API
https://github.com/pymmcore-plus/pymmdevice
Last synced: 5 months ago
JSON representation
Direct Python wrapper for MMDevice API
- Host: GitHub
- URL: https://github.com/pymmcore-plus/pymmdevice
- Owner: pymmcore-plus
- License: bsd-3-clause
- Created: 2024-03-21T16:58:46.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2025-03-03T16:26:54.000Z (over 1 year ago)
- Last Synced: 2025-03-03T17:31:55.788Z (over 1 year ago)
- Language: Python
- Size: 84 KB
- Stars: 2
- Watchers: 2
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# pymmdevice
[](https://github.com/pymmcore-plus/pymmdevice/raw/main/LICENSE)
[](https://pypi.org/project/pymmdevice)
[](https://python.org)
[](https://github.com/pymmcore-plus/pymmdevice/actions/workflows/ci.yml)
[](https://codecov.io/gh/pymmcore-plus/pymmdevice)
Direct, low-level control of Micro-Manager device adapters in Python.
If you want to use Micro-Manager devices directly in Python,
you should install [`pymmcore`](https://github.com/micro-manager/pymmcore)
(or [`pymmcore-plus`](https://github.com/pymmcore-plus/pymmcore-plus))
and instantiate an instance of `pymmcore.CMMCore` (or
`pymmcore_plus.CMMCorePlus`). Then, to load a specific device adapter, you
would call `loadDevice('MyLabel', 'ModuleName', 'DeviceName')`, and control
it via the `CMMCore` instance.
This library is an **experimental** (read: broken) lower-level wrapper around
the MMDevice API that gives you *direct* control over device adapter libraries,
as python wrappers around the various subclasses of
[`MMCore/Devices/DeviceInstance.h`](https://github.com/micro-manager/mmCoreAndDevices/tree/4441b057e65fed8914c58c33e64123b17eeb6b25/MMCore/Devices).
This absolutely opens the possibility of using a device incorrectly, so an
understanding of the MMDevice API is important, and caution is advised. Here be
dragons.
## Installation
```sh
pip install git+https://github.com/pymmcore-plus/pymmdevice.git
```
## Usage
```python
import numpy as np
import pymmdevice as pmmd
pm = pmmd.PluginManager()
lib_dir = (
"/Users/talley/Library/Application Support/pymmcore-plus/mm/Micro-Manager-80d5ac1"
)
pm.SetSearchPaths([lib_dir])
module = pm.GetDeviceAdapter("DemoCamera")
assert "DCam" in module.GetAvailableDeviceNames()
with module.load_camera("DCam", "MyCamera") as cam:
cam.SetBinning(2)
cam.SnapImage()
img = cam.GetImageArray()
assert isinstance(img, np.ndarray)
assert img.shape == (256, 256)
```
## Development
### Clone the repo and initialize the submodules
```sh
git clone https://github.com/pymmcore-plus/pymmdevice.git --recurse-submodules
cd pymmdevice
```
### Create a virtual environment
You can do this however you prefer:
```sh
# e.g
mamba create -n pymmdevice python=3.11
mamba activate pymmdevice
# or
uv venv
source .venv/bin/activate
```
### Install in editable mode *without* build isolation
Meson-python is used to build the pybind11 extension, and editable installs in
meson-python currently require disabling build isolation. See [meson-python
docs](https://meson-python.readthedocs.io/en/latest/how-to-guides/editable-installs.html)
for more information.
This means you must also install the build dependencies manually
before running `pip install -e .`
```sh
pip install meson-python meson ninja pybind11
pip install -e ".[dev]" --no-build-isolation
```
#### Source the micro-manager libraries somewhere
The tests require a compiled `libmmgr_dal_DemoCamera` library from
Micro-Manager. I do this by using the build-dev command from
[pymmcore-plus](https://github.com/pymmcore-plus/pymmcore-plus) (which will have
been installed in the `[dev]` extra above.)
```sh
mmcore build-dev DemoCamera
# or, to install all libraries from the latest release
mmcore install
```
However, if you would like to point to a different location, you can set the
`MM_LIB_DIR` environment variable to the directory containing the compiled
libraries. (This directory must minimally contain `libmmgr_dal_DemoCamera`
for tests to pass.)
### Run tests
Then you can run the tests:
```sh
pytest
```
Note that compiled files end up in `build/` directory and are dynamically loaded
at import time and test time. This means you can make changes to the pybind11
wrapper and simply re-run the tests without re-installing.
### Troubleshooting
- `ERROR: File does not exist.` when building or running `pip install -e .`
You likely didn't initialize the submodules when you cloned the repo. Run:
```sh
git submodule update --init --recursive
```
- General Reset
After the initial install, one problem that can arise occasionally is a stale
`build/` directory. If you encounter errors during the build process, try
removing the `build/` directory and re-installing.
```sh
rm -rf build && pip install -e . --no-build-isolation --force-reinstall
```
### Generating type stubs
```sh
pybind11-stubgen pymmdevice._pymmdevice -o src
```