Coder Social home page Coder Social logo

micro-manager / pymmcore Goto Github PK

View Code? Open in Web Editor NEW
32.0 32.0 9.0 234 KB

Python bindings for MMCore, Micro-Manager's device control layer

Home Page: https://pypi.org/project/pymmcore/

License: GNU Lesser General Public License v2.1

Python 80.19% Dockerfile 1.83% SWIG 17.98%

pymmcore's Introduction

Micro-Manager

Micro-Manager is an application to control microscope hardware, such as cameras, xy-stages, filter wheels, etc. It includes a hardware abstraction layer written in C++ and a user interface written in Java (Swing).

Go to micro-manager.org for documentation and binary downloads.

For support, see Micro-Manager Community.

The Micro-Manager community welcomes you! For our governance structures, go here

Source code

This repository contains the Java projects that make up the Micro-Manager "MMStudio" GUI application. The device control layer is written in C++ and found in a separate repository, mmCoreAndDevices, which is currently a git submodule of this repository.

To checkout both repositories together:

git clone --recurse-submodules https://github.com/micro-manager/micro-manager.git

If you will be making changes to the code, make sure to enable pre-commit hooks as described in doc/pre-commit.md.

Branches

  • main - the main branch of development (Micro-Manager 2.x)
  • svn-mirror - git-svn mirror of the Micro-Manager 1.4 Subversion repository

Other branches are not official.

Developer information

For license information, please see doc/copyright.txt.

For build instructions, please see the doc/how-to-build.md.

Additional information is available on the Micro-Manager website at https://micro-manager.org

Contributing

Start here: https://micro-manager.org/Building_and_debugging_Micro-Manager_source_code

pymmcore's People

Contributors

hinderling avatar ianhi avatar marktsuchida avatar oeway avatar tlambert03 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

pymmcore's Issues

Use python -m build to build

Or at least exercise it in some of our CI scripts (e.g. the Ubuntu build check), to keep pyproject.toml working.

Error second time use of startSequenceAcquisition

Hallo,
I use the MicroManager2.0 to control a Hamamatsu Camera with python.
When I use the function startSequenceAcquisition with NumberofImages = 1 the first time after initialization an image is recorded. When I use his function a second time an error is throwing.

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Micro-Manager-2.0gamma\MMCorePy.py", line 5532, in startSequenceAcqui sition return _MMCorePy.CMMCore_startSequenceAcquisition(self, *args) MMCorePy.CMMError: Error in device "camera": Unknown error in the device (1)

I hope somebody can help me.
Thanks,
Felix

accept type stubs?

I have written type stubs for pymmcore that I find extremely handy. For example, with stubs present in the environment, VScode (and other IDEs) can provide autocompletion, linting, and type validation with mypy:

Untitled 2

Untitled

would you want/be willing to distribute the pyi file in along with this package (see PEP 561)? The one thing I haven't done before is provide type stubs for a single-module package like pymmcore ... but we could figure that out I'm sure.

The alternatives are for me to submit to typeshed, or to distribute a stub-only package.

Import Error on numpy.core.multiarray

importing pymmcore gives an import error in pymmcore.py saying it fails to import numpy.core.multiarray.

Traceback (most recent call last): File "pymmWrap.py", line 1, in <module> import pymmcore File "PyInstaller\loader\pyimod03_importers.py", line 531, in exec_module File "pymmcore.py", line 15, in <module> ImportError: numpy.core.multiarray failed to import

After a while of searching I found that i can fix it by importing numpy in my python file before importing pymmcore but this seems like an error in pymmcore.

Ship DemoCamera with pymmcore

Following the hints in #18, I manage to build a DemoCamera device adapter that works in Docker, it's very helpful for development and demo purpose. So I am wondering whether it make sense to build and ship the demo device adapter directly with pymmcore, so I don't even need to fetch a binary version elsewhere.

Here is the demo jupyter notebook I made: Binder (BTW, we can link to this repo as an example if you like.)

Support mmc.getTaggedImage

The java interface has the getTaggedImage function, perhaps would be good to also make it available in the Python binding?

`threads="1"` breaks `mmc.setSLMImage`

Hi! I'm currently switching our setup from pycromanager to pymmcore(-plus).

As other users already noted, the update from 10.1.1.70.3 to 10.1.1.70.4 breaks mmc.setSLMImage('Mosaic3',mask). I tried with two different microscope setups, SLM devices are Andor Mosaic3 and Mightex Polygon1000, both crash with versions > 10.1.1.70.3. The offending change is the threads argument in %module (package="pymmcore", directors="1", threads="1") pymmcore_swig that was added to pymmcore/pymmcore_swig.i. I got mmc.setSLMImage working in a fork of the newest version (pymmcore 10.4.0.71.1, Micro-Manager_2.0.3_20230925), by changing the line and building from source.

But this re-introduces the kernel crashes as soon as mmc is idle for some time (~500ms), that probably would be fixed with 10.1.1.70.4: When I start taking pictures directly after loading the hardware config, I can change OCs and SLMImages for hundreds of pictures in a loop without issues. But as soon as the loop is done the kernel crashes. In the logs, the last line is always [IFO,Core] Did update system state cache.

Any ideas how to best continue from here?

Failing control of MCL_MicroDrive device

Greetings,

I'm trying to use pymmcore with a Mad City Labs XY stage driver. Whenever I try to set the position (i.e. at [0, 0]) I get RuntimeError: Error in device "MicroDrive": MCL Error: Handle not valid (-8).

In the past I was already able to control the drivers via python by using the ctypes package to wrap the DLL, so I'm not quite sure what's the problem.

A small snippet of example code to reproduce the problem:

import pymmcore

mm_dir = "C:/Program Files/Micro-Manager-2.0"

mmc = pymmcore.CMMCore()
print(mmc.getAPIVersionInfo())
mmc.setDeviceAdapterSearchPaths([mm_dir])
mmc.loadDevice(
    "MicroDrive",
    "MCL_MicroDrive",
    "MicroDrive XY Stage"
)

mmc.setXYPosition("MicroDrive", 0, 0)

This happens regardless of which position I try to set.


EDIT: adding my setup information

OS: Windows 10 (x64)
Python: 3.9.7
MCL DLL version: 2.0
pymmcore version: 10.1.1.70.5

Let me know if you need any other information.

can't install on linux x86_64 py37

I tried pip install pymmcore and it tries to build from source but fails. I tried downloading the wheel and I'm pretty sure I got the right wheel, but pip disagrees:

$ pip install ~/Downloads/pymmcore-10.1.1.70.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl 
pymmcore-10.1.1.70.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl is not a supported wheel on this platform.

version info and stuff:

$ uname -a
Linux akuli-desktop 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 GNU/Linux

$ pip --version
pip 18.1 from /tmp/e/lib/python3.7/site-packages/pip (python 3.7)

Error messages obscured

I've generated errors a few different times using pymmcore and so far the last line of the tracebacks all look like this:

RuntimeError: <Swig Object of type 'CMMError *' at 0x00000210CFAE1870>

It would be helpful to unpack the actual error message here.

Switch to src-layout

As defined here, i.e., just move pymmcore/ to src/pymmcore/.

With the current layout, care needs to be taken when locally testing the build because Python can pick up files in pymmcore/ as part of the pymmcore package.

Unable to Use Pymmcore in Windows 10 64 bit, Anaconda 32 bit

Hi,

I am trying to use Andor iKon L and Apogee Alta F6 camera with pymmcore.

Steps to reproduce the bug:

  1. Windows 10 Pro 64 bit Platform
  2. Download 32 bit anaconda.
  3. Make an virtual environment with python 3.7.11 (Win 32 bit)
  4. conda activate virtual-environment (created in step 3)
  5. install pymmcore using pip (python -m pip)
  6. install Micromanager 2.0 (32 bit).
  7. make configuration files for Andor and Apogee camera using Micromanager hardware wizard. Both the cameras work with micromanager software.

Some Outputs:

(Python3-32-1) C:\Program Files (x86)\Micro-Manager-2.0>python
Python 3.7.11 (default, Jul 27 2021, 09:46:33) [MSC v.1916 32 bit (Intel)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.architecture()
('32bit', 'WindowsPE')
>>> import pymmcore
>>> pymmcore.CMMCore().getAPIVersionInfo()
'Device API version 70, Module API version 10'
>>> mmc = pymmcore.CMMCore()
>>> mm_dir = 'C:\Program Files (x86)\Micro-Manager-2.0'
>>> mmc.setDeviceAdapterSearchPaths([mm_dir])
>>> mmc.loadSystemConfiguration(os.path.join(mm_dir, "AndorIKonL.cfg"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: Line 7: Device,Andor,Andor,Andor
Failed to load device "Andor" from adapter module "Andor" [ Failed to load device adapter "Andor" [ Failed to load module "C:\Program Files (x86)\Micro-Manager-2.0\mmgr_dal_Andor.dll" [ %1 is not a valid Win32 application. ] ] ]
>>>

AndorIKonL.cfg

# Generated by Configurator on Sun Feb 13 11:24:28 IST 2022

# Reset
Property,Core,Initialize,0

# Devices
Device,Andor,Andor,Andor

# Pre-init settings for devices
Property,Andor,Camera,| iKon | DZ936_BV~28 | 17872 |

# Pre-init settings for COM ports

# Hub (parent) references

# Initialize
Property,Core,Initialize,1

# Delays

# Focus directions

# Roles
Property,Core,Camera,Andor
Property,Core,AutoShutter,1

# Camera-synchronized devices

# Labels

# Configuration presets
# Group: Channel

# Group: System
# Preset: Startup

Failure to load Raptor EPIX device

Dear maintainers,
I am having trouble loading a Raptor EPIX camera (https://micro-manager.org/wiki/RaptorEPIX) using pymmcore (py3.8), even though it loads fine with the MicroManager 1.4 GUI interface or with MMCorePy (py2.7).
C:\Program Files\Micro-Manager-1.4 has been added to the $PATH and is the current directory. With MMCorePy, the following works:

>>> import MMCorePy
>>> mmc = MMCorePy.CMMCore()
>>> mmc.loadDevice("Raptor Ninox Camera 640", "RaptorEPIX", "Raptor Ninox Camera 640")
>>> mmc.initializeAllDevices()
>>> mmc.setCameraDevice("Raptor Ninox Camera 640")
>>> mmc.snapImage()

but with pymmcore, the same code (with the modified import) fails at the initializeAllDevices stage with an error from the PIXCI driver:

PIXCI(R) 64 Bit Library 3.08.00 [15.08.31]
PIXCI(R) Configuration Error or Fault
Operating system not supported
Check Configuration!
See Installation and In Case of Trouble in the PIXCI(R) User's Manual.

Current operating system not supported

Is there perhaps anything to do to make pymmcore load the drivers in a way "more similar" to how MMCorePy does it?
Thanks in advance.

Error loading device adapter with pymmcore but not micromanager

Hi,
I have an Andor Zyla and it works with Micromanger 2, however when I try to use it via pymmcore I get the following errors when running the quick example from the readme:

image

I figured this error just might be due to the inserted backslash that happens in mmc.loadSystemConfiguration(os.path.join(mm_dir, "MMConfig_demo.cfg")). So I tried to change directory to the config file and then load it, which gives the following error:

image

Strangely the camera works fine with micromanager, so the issue must be either with pymmcore or some aspect of the mmgr_dal_AndorSDK3.dll that only pymmcore uses. The micromanager folder has been added to PATH.

Any help or fixes for this would be greatly appreciated.

Issue with error handling in `setSLMImage`

Not sure if this belongs here in or in pymmcore but the following code crashes python:

from pymmcore import CMMCore
from pymmcore_plus import CMMCorePlus as CMMCore
core = CMMCore()
try:
    core.setSLMImage("nothing-loaded", "\x01"*512*512)
except Exception as e:
    print(repr(e))

print("did we get here?")

giving the following output:

terminate called after throwing an instance of 'CMMError'
  what():  No device with label "nothing-loaded"
Aborted (core dumped)

While I certainly expect an error to be thrown, I don't expect this cause python to crash, contrast with the same situation for snapImage:

from pymmcore import CMMCore
from pymmcore_plus import CMMCorePlus as CMMCore
core = CMMCore()
try:
    core.snapImage()
except Exception as e:
    print(repr(e))
    pass

print("did we get here?")

which gives:

RuntimeError('Camera not loaded or initialized.')
did we get here?

loading NikonTi2 dll

I am trying to load a configuration based on the Ti2_Mic_Driver.dll, as discussed on the micromanager wiki. It works fine when I load the config file in the micromanager gui, however when I do it through pymmcore, I get an error.

I am using the following code:

import pymmcore
import os.path
mm_dir = "C:/Program Files/Micro-Manager-2.0gamma"
mmc = pymmcore.CMMCore()
mmc.setDeviceAdapterSearchPaths([mm_dir])
mmc.loadSystemConfiguration(os.path.join(mm_dir, "custom.cfg"))

and I get this error message:


OSError Traceback (most recent call last)
in
----> 1 mmc.loadSystemConfiguration(os.path.join(mm_dir, "custom.cfg"))
2
3 mmc.snapImage()
4 mmc.getImage()

OSError: Line 7: Device,Ti2-E__0,NikonTi2,Ti2-E__0
Failed to load device "Ti2-E__0" from adapter module "NikonTi2" [ Failed to load device adapter "NikonTi2" [ Failed to load module "C:/Program Files/Micro-Manager-2.0gamma\mmgr_dal_NikonTi2.dll" [ The module, or a module it depends upon, could not be found (Windows error: The specified module could not be found.) ] ] ]

It is calling the mmgr_dal_NikonTi2.dll file rather than the Ti2_Mic_Driver.dll.

How to control c++ std locally?

Hi @marktsuchida I was trying to get this to build locally (in the context of working on MMCore) and I keep running into the below error. Is there an easy way you can recommend to force this to be c++14?

(pymm) ian@fermented-beans:~/Documents/oss/micro/pymmcore$ python setup.py build_ext -j2
running build_ext
running build_clib
building 'MMDevice' library
gcc -pthread -B /home/ian/mambaforge/envs/pymm/compiler_compat -Wno-unused-result -Wsign-compare -DNDEBUG -fwrapv -O2 -Wall -fPIC -O2 -isystem /home/ian/mambaforge/envs/pymm/include -fPIC -O2 -isystem /home/ian/mambaforge/envs/pymm/include -fPIC -DMODULE_EXPORTS -ImmCoreAndDevices/MMDevice -c mmCoreAndDevices/MMDevice/Debayer.cpp -o build/temp.linux-x86_64-3.10/mmCoreAndDevices/MMDevice/Debayer.o
In file included from mmCoreAndDevices/MMDevice/MMDevice.h:49,
                 from mmCoreAndDevices/MMDevice/ImgBuffer.h:29,
                 from mmCoreAndDevices/MMDevice/Debayer.h:29,
                 from mmCoreAndDevices/MMDevice/Debayer.cpp:26:
mmCoreAndDevices/MMDevice/ImageMetadata.h:325:58: error: ISO C++17 does not allow dynamic exception specifications
  325 |    MetadataSingleTag GetSingleTag(const char* key) const throw (MetadataKeyError)
      |                                                          ^~~~~
mmCoreAndDevices/MMDevice/ImageMetadata.h:332:56: error: ISO C++17 does not allow dynamic exception specifications
  332 |    MetadataArrayTag GetArrayTag(const char* key) const throw (MetadataKeyError)
      |                                                        ^~~~~
error: command '/usr/bin/gcc' failed with exit code 1

Docker image for MicroManager and pymmcore

Hi, I am making a tutorial in Jupyter notebook with pymmcore (see here), and would like to host it on Binder so people can try it easily without any local installation.

My question is, can we make a docker container for micromanager with demo devices? I have been searching around, but only find a linux installation guideline which seems to be outdated. Would be really nice to provide one officially.

DeviceAdapter (TIScam) that works in micro-manager, not working in pymmcore

I'm looking for some tips in debugging an issue wherein a device adapter that works fine in micro-manager proper, fails to load (with missing dependency) in pymmcore:

pymmcore is generally working and the demo config works fine:

In [1]: import pymmcore

In [2]: mmc = pymmcore.CMMCore()

In [3]: mmc.setDeviceAdapterSearchPaths(('C:\\Program Files\\Micro-Manager-2.0gamma',))

In [4]: mmc.loadSystemConfiguration('C:\\Program Files\\Micro-Manager-2.0gamma\\MMConfig_demo.cfg')

In [5]: mmc.getCameraDevice()
Out[5]: 'Camera'

I have a minimal test config with a single TIScam that works fine in the main micro-manager gui (loads and snaps an image)

# c:\\Users\\talley\\Desktop\\test.cfg

# Reset
Property,Core,Initialize,0
# Devices
Device,Camera,TIScam,TIS_DCAM
# Initialize
Property,Core,Initialize,1
# Roles
Property,Core,Camera,Camera
Property,Core,AutoShutter,1

However, when I attempt to load that same config with pymmcore, I get a missing module error:

In [6]: try:
    ...:     mmc.loadSystemConfiguration('c:\\Users\\talley\\Desktop\\test.cfg')
    ...: except Exception as e:
    ...:     print(e.args[0].getFullMsg())
    ...: 
Line 4: Device,Camera,TIScam,TIS_DCAM
Failed to load device "TIS_DCAM" from adapter module "TIScam" 
[ Failed to load device adapter "TIScam" 
	[ Failed to load module "C:\Program Files\Micro-Manager-2.0gamma\mmgr_dal_TIScam.dll" 
		[ The module, or a module it depends upon, could not be found (Windows error: The specified module could not be found.) ] ] ]

In [7]: import os

# but the module itself definitely exists
In [8]: os.path.exists('C:\Program Files\Micro-Manager-2.0gamma\mmgr_dal_TIScam.dll')
Out[8]: True

I'm wondering whether there is some additional library search paths that might be added when running the actual micro-manager GUI that are missing when running via pymmcore? I tried digging a bit with dependency walker, but a lot was missing there. (if there is a section in the micro-manager source code or in the device adapter code that I should be looking through, I'm happy to dig there with some guidance!)

I'm running Win10, py3.8.6, with MM-2.0.0-gamma1-20201220

thank you!
cc @nicost

Move Swig file into this repo

Perhaps. There are quite a few possible improvements/cleanups and they should probably be done here, where we have a semi-independent version number.

Handling assertion errors in MMCore

There are a few places where assert statements are used in MMCore and DeviceBase.h, such as here.

If these lines fail, the python runtime will crash out back to terminal.

Example:

from contextlib import suppress

from pymmcore import CMMCore, StateDevice

core = CMMCore()
mm_path = "/Users/talley/Library/Application Support/pymmcore-plus/mm/Micro-Manager-2.0.2-20230810"
core.setDeviceAdapterSearchPaths([mm_path])
core.loadDevice("StateDev", "DemoCamera", "DWheel")
core.loadDevice("Camera", "DemoCamera", "DCam")

# ============  No problem here, just runtime error  we go on
with suppress(RuntimeError):
    core.getState("NotADevice")

# ============  No problem here: Camera is a device, but not a state device
with suppress(RuntimeError):
    core.getState("Camera")  # Also just 

# ============  Unless we uncomment core.initializeDevice, we abort 
# StateDev IS a state device... but `CreateIntegerProperty(MM::g_Keyword_State`
# hasn't been called by the adapter yet

# core.initializeDevice("StateDev")  # <- the fix
assert core.getDeviceType("StateDev") is StateDevice  # (it is)
with suppress(Exception):  # <- doesn't help
    core.getState("StateDev")  # Abort: GetPosition, file DeviceBase.h, line 2287.

@marktsuchida, curious to hear your thoughts. Is a full crash something we could prevent here? would it be at the level of mmCoreAndDevices (by swapping those asserts for something else), at the level of SWIG (by catching them somehow and re-reraising), or all the way at the level of pymmcore-plus or something, by (laboriously) trying to make sure you don't do something like call getState on an uninitialized stateDevice?

Unable to connect NikonTi microscope (Windows fatal exception: access violation)

I was using pymmcore to control NikonTi microscope and two cameras. We recently received a new computer with Windows 11 on which I am trying to do the same. Everything works well through Micromanager and two cameras can be controlled using python script. However, when trying to connect NikonTi via pymmcore I am receiving an error when loading system configuration
mmc.loadSystemConfiguration(os.path.join(path, config)):

Windows fatal exception: access violation

Main thread:
Thread 0x000016e4 (most recent call first):
  File "C:\Users\User\AppData\Local\Temp\ipykernel_9424\1486552245.py", line 1 in <module>

Restarting kernel... 

(The folder 'ipykernel_9424' does not exist, if I am trying to create it, the number (*_9424) changes)(??)

The event application error on Windows in this case is:

Faulting application name: python.exe, version: 3.9.18150.1013, time stamp: 0x64ff232c
Faulting module name: OLEAUT32.dll, version: 10.0.22621.2506, time stamp: 0x6649ab4c
Exception code: 0xc0000005
Fault offset: 0x000000000000d6f3
Faulting process id: 0x0x20D4
Faulting application start time: 0x0x1DA76E54BE65E12
Faulting application path: C:\Users\User\miniconda3\envs\my_env\python.exe
Faulting module path: C:\Windows\System32\OLEAUT32.dll
Report Id: 90792ce8-3422-4ebb-b350-166a2ef5f09b
Faulting package full name: 
Faulting package-relative application ID: 

The code:

import pymmcore
import os.path

path = 'C:\Program Files\Micro-Manager-2.0'
config = 'NikonTi.cfg' 

mmc.pymmcore.CMMCore()
mmc.setDeviceAdapterSearchPath([path])
mmc.loadSystemConfiguration(os.path.join(path, config))

Everything was installed for 64 bit system. The Micromanager folder was set as a working directory. The same behavior was observed in Spyder, PyCharm and in command prompt(but error is not displayed). I tried different environments with python3.8, 3.9, 3.11. The same result was obtained with Micromanager 2.0 and last Nightly Builds version, by using corresponding versions of pymmcore.

Debugging after load system configuration

After loading the config file through 'loadSystemConfiguration', anytime there is a print statement, there is an error:

OSError: [Errno 9] Bad file descriptor

Is there a reason why that is?

error load Hamamtsu Camera

Hi,

I am getting the following error while trying to load the Hamamatsu Camera by this command:
mmc.loadDevice('Camera','HamamatsuHam', 'HamamatsuHam_DCAM')

or by this command:
mmc.loadSystemConfiguration(os.path.join(mm_dir, "MMConfig_hamamatsu.cfg"))

with the error thrown being the following (which is not very informative to me):
RuntimeError: <Swig Object of type 'CMMError *' at 0x0000014BCB37AEA0>

I moved to pymmcore in order to work under python3

I didn't have any problem with loading the camera while working under python2 and the MMCorePy

any suggestion on this?

Thank you
Rani

getMultiROI appears broken in pymmcore swig

the core void CMMCore::getMultiROI method populates 4 std::vector<unsigned>& with ROI info. The swig conversion doesn't appear to be working?

In [4]: core.getMultiROI([],[],[],[])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 core.getMultiROI([],[],[],[])

TypeError: in method 'CMMCore_getMultiROI', argument 2 of type 'std::vector< unsigned int,std::allocator< unsigned int > > &'

callback system crashing kernel with subclassed `MMEventCallback`

Hi,

I'm using an Olympus IX83 microscope with pymmcore-plus. In https://github.com/tlambert03/pymmcore-plus/issues/21 I found what I thought were issues with pymmcore-plus but on further inspection seem to be issues with pymmcore itself (or perhaps the secret olympus driver).

On this microscope if I register a pure pymmcore.MMEventCallback and then do setConfig then there is no issue and it prints out all the callbacks to the terminal (Though there is some multiple calling of callbacks perhaps)
(These prints come from here: https://github.com/micro-manager/mmCoreAndDevices/blob/97f82b9ef02788d8b6e9aa70283eb10c7c645a6e/MMCore/MMEventCallback.h)

onPropertyChanged() Core Shutter Shutter-1
onPropertyChanged() DiaShutter State 1
onConfigGroupChanged() Channel BF
onPropertyChanged() TransmittedIllumination 1 Brightness 100 
onConfigGroupChanged() Channel BF
onPropertyChanged() EpiShutter 1 State 0
onConfigGroupChanged() Channel BF 

However if I switch to using a subclass of that object that doesn't introduce any changes then my python immediately crashes with no error messages printed anywhere I can see:

class MyCallbacks(pymmcore.MMEventCallback):
    def __init__(self):
        super().__init__()

# cb = pymmcore.MMEventCallback()
cb = MyCallbacks()
mmcore.registerCallback(cb)

I only see this crash when changing the config, if I do something like set the X position then the callback works the same as the pymmcore version.

This is deeply confusing because I thought that subclassing an object like that should be exactly the same as having the same object. However in https://github.com/tlambert03/pymmcore-plus/issues/21#issuecomment-881701240 it was suggested that this may be an incompatibiliity due to nuances with swig:

it's possible that the callback system is subtly incompatible with the SwigPyObject wrapping pymmcore.MMEventCallback (see here for a bit more, and note that pymmcore currently uses the -builtin flag) but that's just a guess.

Any help getting to the bottom of this issue would be greatly appreciated.

export `__version__` in `__init__`

Currently you don't seem to be able to do: from pymmcore import __version__; print(__version__).

It would be nice to be able to do this to check the version during runtime (e.g. when debugging an issue and checking versions)

abort crash in pymmcore.Configuration.getSetting on missing key

I'm wondering if there's any way this crash could be caught more gracefully, even a try/except won't protect this crash:

In [1]: from pymmcore import CMMCore

In [2]: cmm = CMMCore()

In [3]: state = cmm.getSystemState()

In [4]: state.getSetting('Core', 'AutoFocus')
Out[4]: <Swig Object of type 'PropertySetting *' at 0x10c359870>

In [5]: state.getSetting('Core', 'AutoFocs')  # whoops
libc++abi.dylib: terminating with uncaught exception of type
CMMError: Property AutoFocs not found in device Core.
[1]    8235 abort      ipython

note: I know that I can query this object safer programmatically, but curious whether we could also avoid a full crash in this scenario

Hard crash with `waitForConfig()` timeout

I have issues with a Nikon reflector turret TIFilterBLOCK1 timing out leading to kernel crashes. Setup is the following:

for i in range(20): #multiple loops as timeout happens randomly
    for channel in channels: #loop over different configs
        mmc.setConfig('Channel',channel)
        mmc.waitForSystem / mmc.waitForConfig # where I get the error with ~10% chance
  • With waitForSystem() I get a runtime error as expected:
    RuntimeError: Wait for device "TIFilterBlock1" timed out after 5000ms
  • But with waitForConfig('Channel',channel) I get a kernel crash:
    The Kernel crashed while executing code in the the current cell or a previous cell
    or no error at all and the loop keeps running, but I can find the timeout in the log file:
    [ERR,Core] Error occurred in device waitForConfig: Wait for device "TIFilterBlock1" timed out after 5000ms

Seems like in waitForSystem() timeout errors are propagated from waitForDevice()->waitForDeviceType()->waitForSystem()

While in waitForConfig() the errors are caught:

void CMMCore::waitForConfig(const char* group, const char* configName) throw (CMMError)
{
   CheckConfigGroupName(group);
   CheckConfigPresetName(configName);

   Configuration cfg = getConfigData(group, configName);
   try {
      for(size_t i=0; i<cfg.size(); i++)
         waitForDevice(cfg.getSetting(i).getDeviceLabel().c_str());
   } catch (CMMError& err) {
      // trap MM exceptions and keep quiet - this is not a good time to blow up
      logError("waitForConfig", err.getMsg().c_str());
   }
}

So not interrupting and just logging the error with waitForConfig() seems to work as designed in MMCore (although this behaviour was unexpected to me). But could this be linked to the subsequent pymmcore crashes?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.