python-microscope / microscope

Python library for control of microscope devices, supporting hardware triggers and distribution of devices over the network for performance and flexibility.

Home Page:https://www.python-microscope.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Problem when opening Andor camera

JunqingJ opened this issue · comments

I was testing the communication with Andor Zyla 4.2+ camera with the code attached. It worked the first time and then it started to give error saying dependency could not be found. After manually moving the atcore.dll and atutility.dll into anaconda's path, the dependency error was resolved but the camera can no longer be opened with error "AT_ERR_OUTOFRANGE".
I have had a similar problem before when working with andor3 python package where the camera could not be opened due to duplicate .dll files within different path. But current program kept giving me error on dependency if I do not duplicate the .dll file into anaconda's path.

from microscope.cameras.andorsdk3 import AndorSDK3
import queue
import time

camera=AndorSDK3()
camera.set_exposure_time(0.1)

buffer = queue.Queue()

camera.set_client(buffer)
camera.enable()

for i in range(10):
    print(i)
    camera.trigger()  # images go to buffer
    time.sleep(0.002)

camera.disable()

If this worked once and then didn't work again I wonder if the dll is grabbing the hardware and not relinquishing it. Have you tried rebooting the system and seeing if it work again (once). You could also look through the process list and see if there are any python, or other unexpected, processes hanging around. Although with modern systems there are so many processes this is hard to determine unless you are very familiar with a "normal" state.

Also, which line of the code does that error happen? Can you show us the error message with stack trace?

I'm also curios about the actual dll you are using and ensuring that you're getting the dll that you think you are (particularly since you suggest that there's more than one in the system). Try this:

import microscope.cameras.andorsdk3
print(microscope.cameras.andorsdk3.SDK3._stdcall_libraries)

The error "AT_ERR_OUTOFRANGE" according to the SDK3 manual means "Value is outside the maximum and minimum limits", so it's important to know where it happens. The Andor dll can host multiple cameras on one computer so if the initial camera has been fully closed it may be trying to open a second camera, which then doesn't exist.

Here're the complete error messages.
Camera out of range:

Traceback (most recent call last):

  File "C:\Users\MoraesLab\anaconda3\lib\site-packages\microscope\cameras\andorsdk3.py", line 468, in initialize
    self.handle = SDK3.Open(self._index)

  File "C:\Users\MoraesLab\anaconda3\lib\site-packages\microscope\cameras\_SDK3.py", line 228, in __call__
    raise CameraError(self.name, res)

CameraError: when calling AT_Open - AT_ERR_OUTOFRANGE


The above exception was the direct cause of the following exception:

Traceback (most recent call last):

  File "C:\Users\MoraesLab\.spyder-py3\test1.py", line 38, in <module>
    camera=AndorSDK3()

  File "C:\Users\MoraesLab\anaconda3\lib\site-packages\microscope\cameras\andorsdk3.py", line 336, in __init__
    self.initialize()

  File "C:\Users\MoraesLab\anaconda3\lib\site-packages\microscope\cameras\andorsdk3.py", line 470, in initialize
    raise microscope.InitialiseError("Problem opening camera.") from e

InitialiseError: Problem opening camera.

Dependency not found (this one shows atcore.dll isn't found and there is another one for atutility.dll if I do not add that one into the path):

Traceback (most recent call last):

  File "C:\Users\MoraesLab\.spyder-py3\test1.py", line 34, in <module>
    from microscope.cameras.andorsdk3 import AndorSDK3

  File "C:\Users\MoraesLab\anaconda3\lib\site-packages\microscope\cameras\andorsdk3.py", line 34, in <module>
    from microscope.cameras import _SDK3 as SDK3

  File "C:\Users\MoraesLab\anaconda3\lib\site-packages\microscope\cameras\_SDK3.py", line 37, in <module>
    _stdcall_libraries["ATCORE"] = ctypes.WinDLL("atcore")

  File "C:\Users\MoraesLab\anaconda3\lib\ctypes\__init__.py", line 381, in __init__
    self._handle = _dlopen(self._name, mode)

FileNotFoundError: Could not find module 'atcore' (or one of its dependencies). Try using the full path with constructor syntax.

List of libraries after running stdcal_libraries:

{'ATCORE': <WinDLL 'atcore', handle 7ff964c50000 at 0x1c3eab5c400>, 'ATUTIL': <WinDLL 'atutility', handle 7ff9654b0000 at 0x1c3eab5c460>}

The error "AT_ERR_OUTOFRANGE" according to the SDK3 manual means "Value is outside the maximum and minimum limits", so it's important to know where it happens. The Andor dll can host multiple cameras on one computer so if the initial camera has been fully closed it may be trying to open a second camera, which then doesn't exist.

Thanks a lot for suggestions. I have tried rebooting the system and it didn't solve the problem. I have been communicating with the camera through MATLAB, MicroManager and python using andor3 package, I don't need to copy paste any .dll files using those methods so this is why I suspect the multiple .dll files may be the cause of error.

A quick look at the code also show that, by default, it calls with index=0, maybe the clling convention has chnaged since the module was written. What happens if you change the initial call to be

camera=AndorSDK3(index=1)

Also, what version of Python-Microscope are you using? (last release from pypi or from a git checkout).

You shouldn't have multiple versions of the dll laying around on your system if there's no way to ensure which one is being loaded. I suggest you edit microscope/cameras/_SDK3.py to hardcode the filepath for these two dlls (at least while we're debugging this issue and ensure that the issue is not missing dll / incorrect dll being loaded):

    _stdcall_libraries["ATCORE"] = ctypes.WinDLL("atcore")
    _stdcall_libraries["ATUTIL"] = ctypes.WinDLL("atutility")

A quick look at the code also show that, by default, it calls with index=0, maybe the clling convention has chnaged since the module was written. What happens if you change the initial call to be

camera=AndorSDK3(index=1)

The program gave the same OutOfRange error as the default index setting

Strange that it worked once and then not again. It still seems to me like something else must have an open connection to the hardware preventing this code from connecting. Sorry I cant think of any other obvious things to try at the moment.

Can you connect with the Andor software? And if you, does the Andor software tells you what is the camera index?

I don't know what Andor is doing but some cameras have a saved index number (the start from zero is only if you never saved a value). If you changed it somehow, you need to know it's index number.

I just found a very wired solution to my problem. I removed both atcore.dll and atutility.dll from my anaconda path, then ran the Andor3 python package. After it initialized and connected to the camera properly, I then closed the camera. Afterwards, the camera can be opened and communicated through microscope package properly without any issue.
If I reopen the python and using the microscope package directly, it could not find dependency but it fixed itself as soon as Andor3 package is opened and then closed. I have no clue why this happening