python, CMMCore & SLM Device

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

python, CMMCore & SLM Device

StevenF
Hello Micromanager community!

I have been trying to make the use of our microscope automated through the
python wrapper for Micromanager and i have so far been successful!
Unfortunately i have hit a road bloc and i cannot for the life of me find a
solution to it!
I would like to use the setSLMImage() function to upload a binary image to
our Andor Mosaic3, but i keep getting this error :

"*NotImplementedError: Wrong number of arguments for overloaded function
'CMMCore_setSLMImage'.
  Possible C/C++ prototypes are:
    setSLMImage(CMMCore *,char const *,unsigned char *)
    setSLMImage(CMMCore *,char const *,imgRGB32)*"

this function as per the documentation :
https://valelab4.ucsf.edu/~MM/doc/MMCore/html/class_c_m_m_core.html#a5dc89857c321dc6912a3df0d728d4d05
it takes the name of the /device/ and an /unsigned long char*/ for the
image. Now i have tried everything to make this function work but
unfortunately i cannot get the correct format for the unsigned char* (it
seems this is where the problem comes from and not a wrong number of
arguments as the error misleadingly suggests). I have tried giving a numpy
array, transforming the array in the array('B') format, string, you name it
nothing seems to work. I tried googling it, asking coworkers for help but it
vain.

here is an example of the type of script i am trying to make work :

import os
import MMCorePy
import numpy as np
import scipy.misc
import array
import ctypes

MMDriverPATH='C:\Program Files\Micro-Manager-1.4'
configurationPATH='D:/lifeware/Documents/Base.cfg'
os.chdir(MMDriverPATH)
mmc = MMCorePy.CMMCore()
mmc.loadSystemConfiguration(configurationPATH)
mosaic = mmc.getSLMDevice()
mmc.setSLMImage(mosaic, /*img*/)
mmc.displaySLMImage(mosaic)

in this script */img/* is the problematic variable.

Using the Beanshell script from https://micro-manager.org/wiki/Mosaic3 works
fine but i can't make the python version work!

Thanks in advance,

Steven



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: python, CMMCore & SLM Device

Kyle Douglass

Hi Steven,

mmc.setSLMImage(mosaic, /*img*/)
mmc.displaySLMImage(mosaic)

in this script */img/* is the problematic variable.

What is the Python type or NumPy dtype of */img/* in your code? This is just a guess, but it looks like either 1) the setSLMImage() wrapper method is not converting the data type from a Python type to a C type, or 2) the wrapper method might be expecting a ctypes object as its argument.

NumPy has a number of modules that serve as an interface between Python and C by way of ctypes, e.g.

1. https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.ctypes.html
2. https://docs.scipy.org/doc/numpy/reference/generated/numpy.chararray.ctypes.html

In particular

import numpy as np
import ctypes
>>> x
array([[0, 1],
       [2, 3]])
>>> x.ctypes.data
30439712
>>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_long))
<ctypes.LP_c_long object at 0x01F01300>

which is an example given in the second link above. What happens when you try passing the argument as a ctypes.POINTER(ctypes.c_long) ? If this doesn't work, you might want to find this method in the MM code (the Python wrapper, not the C method!) and have a look to see what exactly it's doing with the /*img*/ argument.

Good luck!
Kyle
-- 
Kyle M. Douglass, PhD
Post-doctoral researcher
The Laboratory of Experimental Biophysics
EPFL, Lausanne, Switzerland
http://kmdouglass.github.io
http://leb.epfl.ch

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: python, CMMCore & SLM Device

StevenF
This post was updated on .
Thanks for the reply Kyle!

Just a quick note the *//* are there because i wanted the img variable to be in bold in the text, they are not present in the code of course.

so i have tried what you suggested before and again right now and it's still not working :

i have a .bmp 800*600 pixels image downscaled from a 2048*2048 image.
it is downscaled because the DMD needs a 800*600 pixels image.

here are some examples :
import os
import MMCorePy
import numpy as np
import scipy.misc
import array
import ctypes


>>> x = scipy.misc.imread(img)
>>> x
array([[0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       ...,
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)
>>> x.ctypes.data
225751856L
>>> a = x.ctypes.data_as(ctypes.POINTER(ctypes.c_long))
>>> a
<IPython.utils._process_win32.LP_c_long at 0x6bdebc8>

>>> MMDriverPATH='C:\Program Files\Micro-Manager-1.4'
>>> configurationPATH='D:/lifeware/Documents/Base.cfg'
>>> os.chdir(MMDriverPATH)
>>> mmc = MMCorePy.CMMCore()
>>> mmc.loadSystemConfiguration(configurationPATH)
>>> mosaic = mmc.getSLMDevice()
>>> mmc.setSLMImage(mosaic, a)
 
NotImplementedError: Wrong number of arguments for overloaded function 'CMMCore_setSLMImage'.
  Possible C/C++ prototypes are:
    setSLMImage(CMMCore *,char const *,unsigned char *)
    setSLMImage(CMMCore *,char const *,imgRGB32)
as stated before i tried everything :
>>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_long))
>>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_longlong))
>>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_char))
>>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte))
 this last line is the one i would imagine being correct

i tried  :
>>> im = np.frombuffer(x, dtype='uint8')
array([0, 0, 0, ..., 0, 0, 0], dtype=uint8)
>>> im.ctypes.data_as(ctypes.POINTER(ctypes.c_long))
>>> im.ctypes.data_as(ctypes.POINTER(ctypes.c_longlong))
>>> im.ctypes.data_as(ctypes.POINTER(ctypes.c_char))
>>> im.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte))
and:
>>> J = np.ctypeslib.as_ctypes(im)
<numpy.ctypeslib.c_ubyte_Array_480000 at 0x6bdeac8>
even:
>>> ar = array.array("B")
>>> ar.fromlist(list(J))
>>> type(J)
array.array

this last one was tried because the beanshell script goes like that :
 
import ij.IJ; // Allows access to basic ImageJ utilities.
  proc = IJ.getImage().getProcessor().duplicate(); // Read the current image.
  pixels = proc.getPixels(); // Extract pixels from ImageJ ImageProcessor object.
  mosaic = mmc.getSLMDevice(); // Get the installed name of the Mosaic device.
  mmc.setSLMImage(mosaic, pixels); // Upload the image to the Mosaic.
  mmc.displaySLMImage(mosaic); // Display the Mosaic.

using Ipython i tried to see what was the variable type of
pixels
 which is an array.array

Here is the MM code :
def setSLMImage(self, *args):
        """
        setSLMImage(self, char slmLabel, unsigned char pixels)
        Parameters:
           slmLabel: char const * value
           pixels: unsigned char * value

           slmLabel: char const * value
           pixels: unsigned char * value

        setSLMImage(self, char slmLabel, imgRGB32 pixels)
        Parameters:
           self: CMMCore * value
           slmLabel: char const * value
           pixels: imgRGB32 value

           slmLabel: char const * value
           pixels: imgRGB32 value

        """
        print type(args[1])
        return _MMCorePy.CMMCore_setSLMImage(self, *args)

sorry for the long post but i am really under the impression i tried everything (passing as strings, just the image (read with PIL and scipy) etc..., and it goes without saying but after each variable transformation i tried giving it to mmc.setSLMImage(mosaic, img), but it always gives the same error.

looking at the python code has not helped that much and i don't want to transform the image in imgRGB32 format. I could try the IJ library like the beanshell script but it's in Jython and i'd rather just use plain old python.

Thanks,

Steven
--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
micro-manager-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: python, CMMCore & SLM Device

StevenF
Edited my last post because it had removed all the code :/!



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: python, CMMCore & SLM Device

Kyle Douglass
In reply to this post by StevenF
Hi Steven,

A NotImplementedError is a built in exception in Python. I checked its
documentation and, if it is being used correctly, then it actually
indicates that this functionality has not been included in the Python
wrapper around MM's core.

https://docs.python.org/3/library/exceptions.html#NotImplementedError

In Python, the programmer is free to raise whatever exception he or she
wishes; this means that when you see this error it doesn't necessarily
mean that the wrapper for this function hasn't been written. It does
provide some evidence that the method is missing from the Python
wrapper, though.

I also looked for the setSLMImage() method in the MM code on Github but
couldn't find any file that relates to the Python wrapper that contained
its signature. However, SWIG (?) might be generating the wrappers during
the Micro-Manager build, so this isn't conclusive evidence either that
it's outright missing.

I'm sorry I can't provide any definite help on this one :/

Kyle

--
Kyle M. Douglass, PhD
Post-doctoral researcher
The Laboratory of Experimental Biophysics
EPFL, Lausanne, Switzerland
http://kmdouglass.github.io
http://leb.epfl.ch


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: python, CMMCore & SLM Device

StevenF
Thanks for the Help Kyle,

I just saw your reply now and will look deeper into this hopefully i will be
able to solve this problem! I Will update if i am able to solve the problem!

Thanks again,

Steven



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general